Cabana 0.8.0-dev
 
Loading...
Searching...
No Matches
Cabana_Grid_HypreSemiStructuredSolver.hpp
Go to the documentation of this file.
1/****************************************************************************
2 * Copyright (c) 2018-2023 by the Cabana authors *
3 * All rights reserved. *
4 * *
5 * This file is part of the Cabana library. Cabana is distributed under a *
6 * BSD 3-clause license. For the licensing terms see the LICENSE file in *
7 * the top-level directory. *
8 * *
9 * SPDX-License-Identifier: BSD-3-Clause *
10 ****************************************************************************/
11
16#ifndef CABANA_GRID_HYPRESEMISTRUCTUREDSOLVER_HPP
17#define CABANA_GRID_HYPRESEMISTRUCTUREDSOLVER_HPP
18
19#include <Cabana_Grid_Array.hpp>
21#include <Cabana_Grid_Hypre.hpp>
24#include <Cabana_Grid_Types.hpp>
25
26#include <HYPRE_config.h>
27#include <HYPRE_sstruct_ls.h>
28#include <HYPRE_sstruct_mv.h>
29#include <HYPRE_struct_ls.h>
30#include <HYPRE_struct_mv.h>
31
32#include <Kokkos_Core.hpp>
33#include <Kokkos_Profiling_ScopedRegion.hpp>
34
35#include <array>
36#include <memory>
37#include <numeric>
38#include <sstream>
39#include <string>
40#include <type_traits>
41#include <vector>
42
43namespace Cabana
44{
45namespace Grid
46{
47
48//---------------------------------------------------------------------------//
50template <class Scalar, class EntityType, class MemorySpace>
52{
53 public:
55 using entity_type = EntityType;
57 using memory_space = MemorySpace;
59 using value_type = Scalar;
61 const int object_type = HYPRE_SSTRUCT;
64 "HYPRE not compatible with solver memory space" );
65
73 template <class ArrayLayout_t>
74 HypreSemiStructuredSolver( const ArrayLayout_t& layout, int n_vars,
75 const bool is_preconditioner = false )
76 : _comm( layout.localGrid()->globalGrid().comm() )
77 , _is_preconditioner( is_preconditioner )
78 {
79 HYPRE_Init();
80
82 "Must use an array layout" );
83 static_assert(
84 std::is_same<typename ArrayLayout_t::entity_type,
85 entity_type>::value,
86 "Array layout entity type mush match solver entity type" );
87
88 // Spatial dimension.
89 const std::size_t num_space_dim = ArrayLayout_t::num_space_dim;
90
91 // Only a single part grid is supported initially
92 int n_parts = 1;
93 int part = 0;
94
95 // Only create data structures if this is not a preconditioner.
96 if ( !_is_preconditioner )
97 {
98 // Create the grid.
99 auto error = HYPRE_SStructGridCreate( _comm, num_space_dim, n_parts,
100 &_grid );
101 checkHypreError( error );
102
103 // Get the global index space spanned by the local grid on this
104 // rank. Note that the upper bound is not a bound but rather the
105 // last index as this is what Hypre wants. Note that we reordered
106 // this to KJI from IJK to be consistent with HYPRE ordering. By
107 // setting up the grid like this, HYPRE will then want layout-right
108 // data indexed as (i,j,k) or (i,j,k,l) which will allow us to
109 // directly use Kokkos::deep_copy to move data between arrays and
110 // HYPRE data structures.
111 auto global_space = layout.indexSpace( Own(), Global() );
112 _lower.resize( num_space_dim );
113 _upper.resize( num_space_dim );
114 for ( std::size_t d = 0; d < num_space_dim; ++d )
115 {
116 _lower[d] = static_cast<HYPRE_Int>(
117 global_space.min( num_space_dim - d - 1 ) );
118 _upper[d] = static_cast<HYPRE_Int>(
119 global_space.max( num_space_dim - d - 1 ) - 1 );
120 }
121 error = HYPRE_SStructGridSetExtents( _grid, part, _lower.data(),
122 _upper.data() );
123 checkHypreError( error );
124
125 // Get periodicity. Note we invert the order of this to KJI as well.
126 const auto& global_grid = layout.localGrid()->globalGrid();
127 HYPRE_Int periodic[num_space_dim];
128 for ( std::size_t d = 0; d < num_space_dim; ++d )
129 periodic[num_space_dim - 1 - d] =
130 global_grid.isPeriodic( d )
131 ? layout.localGrid()->globalGrid().globalNumEntity(
132 EntityType(), d )
133 : 0;
134 error = HYPRE_SStructGridSetPeriodic( _grid, part, periodic );
135 checkHypreError( error );
136
137 // Set the variables on the HYPRE grid
138 std::vector<HYPRE_SStructVariable> vartypes;
139 vartypes.resize( n_vars );
140 for ( int i = 0; i < n_vars; ++i )
141 {
142 vartypes[i] = HYPRE_SSTRUCT_VARIABLE_CELL;
143 }
144 error = HYPRE_SStructGridSetVariables( _grid, part, n_vars,
145 vartypes.data() );
146
147 // Assemble the grid.
148 error = HYPRE_SStructGridAssemble( _grid );
149 checkHypreError( error );
150
151 // Allocate LHS and RHS vectors and initialize to zero. Note that we
152 // are fixing the views under these vectors to layout-right.
153
154 std::array<long, num_space_dim + 1> reorder_size;
155 for ( std::size_t d = 0; d < num_space_dim; ++d )
156 {
157 reorder_size[d] = global_space.extent( d );
158 }
159 reorder_size.back() = n_vars;
160 IndexSpace<num_space_dim + 1> reorder_space( reorder_size );
161 auto vector_values =
163 "vector_values0", reorder_space );
164 Kokkos::deep_copy( vector_values, 0.0 );
165
166 _stencils.resize( n_vars );
167 _stencil_size.resize( n_vars );
168 _stencil_index.resize( n_vars,
169 std::vector<unsigned>( n_vars + 1 ) );
170
171 error = HYPRE_SStructVectorCreate( _comm, _grid, &_b );
172 checkHypreError( error );
173 error = HYPRE_SStructVectorSetObjectType( _b, object_type );
174 checkHypreError( error );
175 error = HYPRE_SStructVectorInitialize( _b );
176 checkHypreError( error );
177 for ( int i = 0; i < n_vars; ++i )
178 {
179 error = HYPRE_SStructVectorSetBoxValues(
180 _b, part, _lower.data(), _upper.data(), i,
181 vector_values.data() );
182 checkHypreError( error );
183 }
184 error = HYPRE_SStructVectorAssemble( _b );
185 checkHypreError( error );
186
187 error = HYPRE_SStructVectorCreate( _comm, _grid, &_x );
188 checkHypreError( error );
189 error = HYPRE_SStructVectorSetObjectType( _x, object_type );
190 checkHypreError( error );
191 error = HYPRE_SStructVectorInitialize( _x );
192 checkHypreError( error );
193 for ( int i = 0; i < n_vars; ++i )
194 {
195 error = HYPRE_SStructVectorSetBoxValues(
196 _x, part, _lower.data(), _upper.data(), i,
197 vector_values.data() );
198 checkHypreError( error );
199 }
200 checkHypreError( error );
201 error = HYPRE_SStructVectorAssemble( _x );
202 checkHypreError( error );
203 }
204 }
205
206 // Destructor.
208 {
209 // We only make data if this is not a preconditioner.
210 if ( !_is_preconditioner )
211 {
212 HYPRE_SStructVectorDestroy( _x );
213 HYPRE_SStructVectorDestroy( _b );
214 HYPRE_SStructMatrixDestroy( _A );
215 for ( std::size_t i = 0; i < _stencils.size(); ++i )
216 {
217 HYPRE_SStructStencilDestroy( _stencils[i] );
218 }
219 HYPRE_SStructGridDestroy( _grid );
220 HYPRE_SStructGraphDestroy( _graph );
221
222 HYPRE_Finalize();
223 }
224 }
225
227 bool isPreconditioner() const { return _is_preconditioner; }
228
239 void createMatrixStencil( int NumSpaceDim, int var = 0, int n_vars = 3,
240 std::vector<unsigned> stencil_length = { 7, 7,
241 7 } )
242 {
243 // This function is only valid for non-preconditioners.
244 if ( _is_preconditioner )
245 throw std::logic_error(
246 "Cannot call createMatrixStencil() on preconditioners" );
247
248 // Generate the stencil indexing
249 unsigned index = 0;
250 for ( int i = 0; i < n_vars; ++i )
251 {
252 _stencil_index[var][i] = index;
253 index += stencil_length[i];
254 }
255 _stencil_index[var][n_vars] = index;
256
257 // Create the stencil.
258 _stencil_size[var] = index;
259 auto error = HYPRE_SStructStencilCreate(
260 NumSpaceDim, _stencil_size[var], &_stencils[var] );
261 checkHypreError( error );
262 }
263
273 template <std::size_t NumSpaceDim>
274 void
275 setMatrixStencil( const std::vector<std::array<int, NumSpaceDim>>& stencil,
276 int var = 0, int dep = 0 )
277 {
278 // This function is only valid for non-preconditioners.
279 if ( _is_preconditioner )
280 throw std::logic_error(
281 "Cannot call setMatrixStencil() on preconditioners" );
282
283 std::array<HYPRE_Int, NumSpaceDim> offset;
284
285 auto index = _stencil_index[var][dep];
286 for ( unsigned n = index; n < index + stencil.size(); ++n )
287 {
288 for ( std::size_t d = 0; d < NumSpaceDim; ++d )
289 offset[d] = stencil[n - index][d];
290 auto error = HYPRE_SStructStencilSetEntry( _stencils[var], n,
291 offset.data(), dep );
292 checkHypreError( error );
293 }
294 }
295
301 void setSolverGraph( int n_vars )
302 {
303 // This function is only valid for non-preconditioners.
304 if ( _is_preconditioner )
305 throw std::logic_error(
306 "Cannot call setSolverGraph() on preconditioners" );
307
308 int part = 0;
309
310 // Setup the Graph for the non-zero structure of the matrix
311 // Create the graph with hypre
312 auto error = HYPRE_SStructGraphCreate( _comm, _grid, &_graph );
313 checkHypreError( error );
314
315 // Set up the object type
316 error = HYPRE_SStructGraphSetObjectType( _graph, object_type );
317 checkHypreError( error );
318
319 // Set the stencil to the graph
320 for ( int i = 0; i < n_vars; ++i )
321 {
322 error =
323 HYPRE_SStructGraphSetStencil( _graph, part, i, _stencils[i] );
324 checkHypreError( error );
325 }
326
327 // Assemble the graph
328 error = HYPRE_SStructGraphAssemble( _graph );
329 checkHypreError( error );
330
331 // Create the matrix. must be done after graph is assembled
332 error = HYPRE_SStructMatrixCreate( _comm, _graph, &_A );
333 checkHypreError( error );
334
335 // Set the SStruct matrix object type
336 error = HYPRE_SStructMatrixSetObjectType( _A, object_type );
337 checkHypreError( error );
338
339 // Prepare the matrix for setting values
340 error = HYPRE_SStructMatrixInitialize( _A );
341 checkHypreError( error );
342 }
343
356 template <class Array_t>
357 void setMatrixValues( const Array_t& values, int v_x, int v_h )
358 {
359 static_assert( is_array<Array_t>::value, "Must use an array" );
360 static_assert(
361 std::is_same<typename Array_t::entity_type, entity_type>::value,
362 "Array entity type mush match solver entity type" );
363 static_assert(
364 std::is_same<typename Array_t::memory_space, MemorySpace>::value,
365 "Array device type and solver device type are different." );
366
367 static_assert(
368 std::is_same<typename Array_t::value_type, value_type>::value,
369 "Array value type and solver value type are different." );
370
371 // This function is only valid for non-preconditioners.
372 if ( _is_preconditioner )
373 throw std::logic_error(
374 "Cannot call setMatrixValues() on preconditioners" );
375
376 int index_size =
377 _stencil_index[v_h][v_x + 1] - _stencil_index[v_h][v_x];
378
379 // Ensure the values array matches up in dimension with the stencil size
380 if ( values.layout()->dofsPerEntity() !=
381 static_cast<int>( index_size ) )
382 throw std::runtime_error(
383 "Number of matrix values does not match stencil size" );
384
385 // Spatial dimension.
386 const std::size_t num_space_dim = Array_t::num_space_dim;
387
388 int part = 0;
389
390 // Copy the matrix entries into HYPRE. The HYPRE layout is fixed as
391 // layout-right.
392 auto owned_space = values.layout()->indexSpace( Own(), Local() );
393 std::array<long, num_space_dim + 1> reorder_size;
394 for ( std::size_t d = 0; d < num_space_dim; ++d )
395 {
396 reorder_size[d] = owned_space.extent( d );
397 }
398
399 reorder_size.back() = index_size;
400 IndexSpace<num_space_dim + 1> reorder_space( reorder_size );
401 auto a_values =
403 "a_values", reorder_space );
404
405 auto values_subv = createSubview( values.view(), owned_space );
406 Kokkos::deep_copy( a_values, values_subv );
407
408 // Insert values into the HYPRE matrix.
409 std::vector<HYPRE_Int> indices( index_size );
410 int start = _stencil_index[v_h][v_x];
411 std::iota( indices.begin(), indices.end(), start );
412 auto error = HYPRE_SStructMatrixSetBoxValues(
413 _A, part, _lower.data(), _upper.data(), v_h, indices.size(),
414 indices.data(), a_values.data() );
415 checkHypreError( error );
416 }
417
422 void printMatrix( const char* prefix )
423 {
424 HYPRE_SStructMatrixPrint( prefix, _A, 0 );
425 }
426
431 void printLHS( const char* prefix )
432 {
433 HYPRE_SStructVectorPrint( prefix, _x, 0 );
434 }
435
440 void printRHS( const char* prefix )
441 {
442 HYPRE_SStructVectorPrint( prefix, _b, 0 );
443 }
444
446 void setTolerance( const double tol ) { this->setToleranceImpl( tol ); }
447
449 void setMaxIter( const int max_iter ) { this->setMaxIterImpl( max_iter ); }
450
452 void setPrintLevel( const int print_level )
453 {
454 this->setPrintLevelImpl( print_level );
455 }
456
458 void
460 Scalar, EntityType, MemorySpace>>& preconditioner )
461 {
462 // This function is only valid for non-preconditioners.
463 if ( _is_preconditioner )
464 throw std::logic_error(
465 "Cannot call setPreconditioner() on a preconditioner" );
466
467 // Only a preconditioner can be used as a preconditioner.
468 if ( !preconditioner->isPreconditioner() )
469 throw std::logic_error( "Not a preconditioner" );
470
471 _preconditioner = preconditioner;
472 this->setPreconditionerImpl( *_preconditioner );
473 }
474
476 void setup()
477 {
478 // This function is only valid for non-preconditioners.
479 if ( _is_preconditioner )
480 throw std::logic_error( "Cannot call setup() on preconditioners" );
481
482 auto error = HYPRE_SStructMatrixAssemble( _A );
483 checkHypreError( error );
484
485 this->setupImpl();
486 }
487
494 template <class Array_t>
495 void solve( const Array_t& b, Array_t& x, int n_vars = 3 )
496 {
497 Kokkos::Profiling::ScopedRegion region(
498 "Cabana::Grid::HypreSemiStructuredSolver::solve" );
499
500 static_assert( is_array<Array_t>::value, "Must use an array" );
501 static_assert(
502 std::is_same<typename Array_t::entity_type, entity_type>::value,
503 "Array entity type mush match solver entity type" );
504 static_assert(
505 std::is_same<typename Array_t::memory_space, MemorySpace>::value,
506 "Array device type and solver device type are different." );
507
508 static_assert(
509 std::is_same<typename Array_t::value_type, value_type>::value,
510 "Array value type and solver value type are different." );
511
512 // This function is only valid for non-preconditioners.
513 if ( _is_preconditioner )
514 throw std::logic_error( "Cannot call solve() on preconditioners" );
515
516 // Spatial dimension.
517 const std::size_t num_space_dim = Array_t::num_space_dim;
518
519 int part = 0;
520
521 // Copy the RHS into HYPRE. The HYPRE layout is fixed as layout-right.
522 auto owned_space = b.layout()->indexSpace( Own(), Local() );
523 std::array<long, num_space_dim + 1> reorder_min;
524 std::array<long, num_space_dim + 1> reorder_max;
525 for ( std::size_t d = 0; d < num_space_dim; ++d )
526 {
527 reorder_min[d] = owned_space.min( d );
528 reorder_max[d] = owned_space.max( d );
529 }
530
531 // Insert b values into the HYPRE vector.
532 // The process of creating the view and then deep copying each
533 // variable is functional, but we should avoid this process
534 // for performance if possible
535 int error;
536 for ( int var = 0; var < n_vars; ++var )
537 {
538 reorder_min.back() = var;
539 reorder_max.back() = var + 1;
540
541 IndexSpace<num_space_dim + 1> reorder_space( reorder_min,
542 reorder_max );
543 auto b_values =
545 "vector_values", reorder_space );
546 // Extract one variable at at time.
547 auto b_subv = createSubview( b.view(), reorder_space );
548
549 Kokkos::deep_copy( b_values, b_subv );
550 error = HYPRE_SStructVectorSetBoxValues(
551 _b, part, _lower.data(), _upper.data(), var, b_values.data() );
552 checkHypreError( error );
553 }
554
555 error = HYPRE_SStructVectorAssemble( _b );
556 checkHypreError( error );
557
558 // Solve the problem
559 this->solveImpl();
560
561 // Extract the solution from the LHS
562 for ( int var = 0; var < n_vars; ++var )
563 {
564 reorder_min.back() = var;
565 reorder_max.back() = var + 1;
566
567 IndexSpace<num_space_dim + 1> reorder_space( reorder_min,
568 reorder_max );
569 auto x_values =
571 "vector_values", reorder_space );
572
573 // Extract one variable at at time.
574 // Use a pair here to retain the view rank.
575
576 error = HYPRE_SStructVectorGetBoxValues(
577 _x, part, _lower.data(), _upper.data(), var, x_values.data() );
578 checkHypreError( error );
579
580 // Copy the HYPRE solution to the LHS.
581 auto x_subv = createSubview( x.view(), reorder_space );
582 Kokkos::deep_copy( x_subv, x_values );
583 }
584 }
585
587 int getNumIter() { return this->getNumIterImpl(); }
588
591 {
593 }
594
596 virtual HYPRE_SStructSolver getHypreSolver() const = 0;
598 virtual HYPRE_PtrToSStructSolverFcn getHypreSetupFunction() const = 0;
600 virtual HYPRE_PtrToSStructSolverFcn getHypreSolveFunction() const = 0;
601
602 protected:
604 virtual void setToleranceImpl( const double tol ) = 0;
605
607 virtual void setMaxIterImpl( const int max_iter ) = 0;
608
610 virtual void setPrintLevelImpl( const int print_level ) = 0;
611
613 virtual void setupImpl() = 0;
614
616 virtual void solveImpl() = 0;
617
619 virtual int getNumIterImpl() = 0;
620
623
627 preconditioner ) = 0;
628
630 void checkHypreError( const int error ) const
631 {
632 if ( error > 0 )
633 {
634 char error_msg[256];
635 HYPRE_DescribeError( error, error_msg );
636 std::stringstream out;
637 out << "HYPRE semi-structured solver error: ";
638 out << error << " " << error_msg;
639 HYPRE_ClearError( error );
640 throw std::runtime_error( out.str() );
641 }
642 }
643
645 HYPRE_SStructMatrix _A;
647 HYPRE_SStructVector _b;
649 HYPRE_SStructVector _x;
650
651 private:
652 MPI_Comm _comm;
653 bool _is_preconditioner;
654 HYPRE_SStructGrid _grid;
655 std::vector<HYPRE_Int> _lower;
656 std::vector<HYPRE_Int> _upper;
657 std::vector<HYPRE_SStructStencil> _stencils;
658 HYPRE_SStructGraph _graph;
659 std::vector<unsigned> _stencil_size;
660 std::vector<std::vector<unsigned>> _stencil_index;
661 std::shared_ptr<HypreSemiStructuredSolver<Scalar, EntityType, MemorySpace>>
662 _preconditioner;
663};
664
665//---------------------------------------------------------------------------//
667template <class Scalar, class EntityType, class MemorySpace>
669 : public HypreSemiStructuredSolver<Scalar, EntityType, MemorySpace>
670{
671 public:
673 using base_type =
676 template <class ArrayLayout_t>
677 HypreSemiStructPCG( const ArrayLayout_t& layout, int n_vars,
678 const bool is_preconditioner = false )
679 : base_type( layout, n_vars, is_preconditioner )
680 {
681 if ( is_preconditioner )
682 throw std::logic_error(
683 "HYPRE PCG cannot be used as a preconditioner" );
684
685 auto error = HYPRE_SStructPCGCreate(
686 layout.localGrid()->globalGrid().comm(), &_solver );
687 this->checkHypreError( error );
688
689 HYPRE_SStructPCGSetTwoNorm( _solver, 1 );
690 }
691
692 ~HypreSemiStructPCG() { HYPRE_SStructPCGDestroy( _solver ); }
693
694 // PCG SETTINGS
695
697 void setAbsoluteTol( const double tol )
698 {
699 auto error = HYPRE_SStructPCGSetAbsoluteTol( _solver, tol );
700 this->checkHypreError( error );
701 }
702
705 void setRelChange( const int rel_change )
706 {
707 auto error = HYPRE_SStructPCGSetRelChange( _solver, rel_change );
708 this->checkHypreError( error );
709 }
710
712 void setLogging( const int logging )
713 {
714 auto error = HYPRE_SStructPCGSetLogging( _solver, logging );
715 this->checkHypreError( error );
716 }
717
718 HYPRE_SStructSolver getHypreSolver() const override { return _solver; }
719 HYPRE_PtrToSStructSolverFcn getHypreSetupFunction() const override
720 {
721 return HYPRE_SStructPCGSetup;
722 }
723 HYPRE_PtrToSStructSolverFcn getHypreSolveFunction() const override
724 {
725 return HYPRE_SStructPCGSolve;
726 }
727
728 protected:
729 void setToleranceImpl( const double tol ) override
730 {
731 auto error = HYPRE_SStructPCGSetTol( _solver, tol );
732 this->checkHypreError( error );
733 }
734
735 void setMaxIterImpl( const int max_iter ) override
736 {
737 auto error = HYPRE_SStructPCGSetMaxIter( _solver, max_iter );
738 this->checkHypreError( error );
739 }
740
741 void setPrintLevelImpl( const int print_level ) override
742 {
743 auto error = HYPRE_SStructPCGSetPrintLevel( _solver, print_level );
744 this->checkHypreError( error );
745 }
746
747 void setupImpl() override
748 {
749 auto error = HYPRE_SStructPCGSetup( _solver, _A, _b, _x );
750 this->checkHypreError( error );
751 }
752
753 void solveImpl() override
754 {
755 auto error = HYPRE_SStructPCGSolve( _solver, _A, _b, _x );
756 this->checkHypreError( error );
757 }
758
759 int getNumIterImpl() override
760 {
761 HYPRE_Int num_iter;
762 auto error = HYPRE_SStructPCGGetNumIterations( _solver, &num_iter );
763 this->checkHypreError( error );
764 return num_iter;
765 }
766
768 {
769 HYPRE_Real norm;
770 auto error =
771 HYPRE_SStructPCGGetFinalRelativeResidualNorm( _solver, &norm );
772 this->checkHypreError( error );
773 return norm;
774 }
775
778 preconditioner ) override
779 {
780 auto error = HYPRE_SStructPCGSetPrecond(
781 _solver, preconditioner.getHypreSolveFunction(),
782 preconditioner.getHypreSetupFunction(),
783 preconditioner.getHypreSolver() );
784 this->checkHypreError( error );
785 }
786
787 private:
788 HYPRE_SStructSolver _solver;
789 using base_type::_A;
790 using base_type::_b;
791 using base_type::_x;
792};
793
794//---------------------------------------------------------------------------//
796template <class Scalar, class EntityType, class MemorySpace>
798 : public HypreSemiStructuredSolver<Scalar, EntityType, MemorySpace>
799{
800 public:
802 using base_type =
805 template <class ArrayLayout_t>
806 HypreSemiStructGMRES( const ArrayLayout_t& layout, int n_vars,
807 const bool is_preconditioner = false )
808 : base_type( layout, n_vars, is_preconditioner )
809 {
810 if ( is_preconditioner )
811 throw std::logic_error(
812 "HYPRE GMRES cannot be used as a preconditioner" );
813
814 auto error = HYPRE_SStructGMRESCreate(
815 layout.localGrid()->globalGrid().comm(), &_solver );
816 this->checkHypreError( error );
817 }
818
819 ~HypreSemiStructGMRES() { HYPRE_SStructGMRESDestroy( _solver ); }
820
821 // GMRES SETTINGS
822
824 void setAbsoluteTol( const double tol )
825 {
826 auto error = HYPRE_SStructGMRESSetAbsoluteTol( _solver, tol );
827 this->checkHypreError( error );
828 }
829
831 void setKDim( const int k_dim )
832 {
833 auto error = HYPRE_SStructGMRESSetKDim( _solver, k_dim );
834 this->checkHypreError( error );
835 }
836
838 void setLogging( const int logging )
839 {
840 auto error = HYPRE_SStructGMRESSetLogging( _solver, logging );
841 this->checkHypreError( error );
842 }
843
844 HYPRE_SStructSolver getHypreSolver() const override { return _solver; }
845 HYPRE_PtrToSStructSolverFcn getHypreSetupFunction() const override
846 {
847 return HYPRE_SStructGMRESSetup;
848 }
849 HYPRE_PtrToSStructSolverFcn getHypreSolveFunction() const override
850 {
851 return HYPRE_SStructGMRESSolve;
852 }
853
854 protected:
855 void setToleranceImpl( const double tol ) override
856 {
857 auto error = HYPRE_SStructGMRESSetTol( _solver, tol );
858 this->checkHypreError( error );
859 }
860
861 void setMaxIterImpl( const int max_iter ) override
862 {
863 auto error = HYPRE_SStructGMRESSetMaxIter( _solver, max_iter );
864 this->checkHypreError( error );
865 }
866
867 void setPrintLevelImpl( const int print_level ) override
868 {
869 auto error = HYPRE_SStructGMRESSetPrintLevel( _solver, print_level );
870 this->checkHypreError( error );
871 }
872
873 void setupImpl() override
874 {
875 auto error = HYPRE_SStructGMRESSetup( _solver, _A, _b, _x );
876 this->checkHypreError( error );
877 }
878
879 void solveImpl() override
880 {
881 auto error = HYPRE_SStructGMRESSolve( _solver, _A, _b, _x );
882 this->checkHypreError( error );
883 }
884
885 int getNumIterImpl() override
886 {
887 HYPRE_Int num_iter;
888 auto error = HYPRE_SStructGMRESGetNumIterations( _solver, &num_iter );
889 this->checkHypreError( error );
890 return num_iter;
891 }
892
894 {
895 HYPRE_Real norm;
896 auto error =
897 HYPRE_SStructGMRESGetFinalRelativeResidualNorm( _solver, &norm );
898 this->checkHypreError( error );
899 return norm;
900 }
901
904 preconditioner ) override
905 {
906 auto error = HYPRE_SStructGMRESSetPrecond(
907 _solver, preconditioner.getHypreSolveFunction(),
908 preconditioner.getHypreSetupFunction(),
909 preconditioner.getHypreSolver() );
910 this->checkHypreError( error );
911 }
912
913 private:
914 HYPRE_SStructSolver _solver;
915 using base_type::_A;
916 using base_type::_b;
917 using base_type::_x;
918};
919
920//---------------------------------------------------------------------------//
922template <class Scalar, class EntityType, class MemorySpace>
924 : public HypreSemiStructuredSolver<Scalar, EntityType, MemorySpace>
925{
926 public:
928 using base_type =
931 template <class ArrayLayout_t>
932 HypreSemiStructBiCGSTAB( const ArrayLayout_t& layout,
933 const bool is_preconditioner = false,
934 int n_vars = 3 )
935 : base_type( layout, n_vars, is_preconditioner )
936 {
937 if ( is_preconditioner )
938 throw std::logic_error(
939 "HYPRE BiCGSTAB cannot be used as a preconditioner" );
940
941 auto error = HYPRE_SStructBiCGSTABCreate(
942 layout.localGrid()->globalGrid().comm(), &_solver );
943 this->checkHypreError( error );
944 }
945
946 ~HypreSemiStructBiCGSTAB() { HYPRE_SStructBiCGSTABDestroy( _solver ); }
947
948 // BiCGSTAB SETTINGS
949
951 void setAbsoluteTol( const double tol )
952 {
953 auto error = HYPRE_SStructBiCGSTABSetAbsoluteTol( _solver, tol );
954 this->checkHypreError( error );
955 }
956
958 void setLogging( const int logging )
959 {
960 auto error = HYPRE_SStructBiCGSTABSetLogging( _solver, logging );
961 this->checkHypreError( error );
962 }
963
964 HYPRE_SStructSolver getHypreSolver() const override { return _solver; }
965 HYPRE_PtrToSStructSolverFcn getHypreSetupFunction() const override
966 {
967 return HYPRE_SStructBiCGSTABSetup;
968 }
969 HYPRE_PtrToSStructSolverFcn getHypreSolveFunction() const override
970 {
971 return HYPRE_SStructBiCGSTABSolve;
972 }
973
974 protected:
975 void setToleranceImpl( const double tol ) override
976 {
977 auto error = HYPRE_SStructBiCGSTABSetTol( _solver, tol );
978 this->checkHypreError( error );
979 }
980
981 void setMaxIterImpl( const int max_iter ) override
982 {
983 auto error = HYPRE_SStructBiCGSTABSetMaxIter( _solver, max_iter );
984 this->checkHypreError( error );
985 }
986
987 void setPrintLevelImpl( const int print_level ) override
988 {
989 auto error = HYPRE_SStructBiCGSTABSetPrintLevel( _solver, print_level );
990 this->checkHypreError( error );
991 }
992
993 void setupImpl() override
994 {
995 auto error = HYPRE_SStructBiCGSTABSetup( _solver, _A, _b, _x );
996 this->checkHypreError( error );
997 }
998
999 void solveImpl() override
1000 {
1001 auto error = HYPRE_SStructBiCGSTABSolve( _solver, _A, _b, _x );
1002 this->checkHypreError( error );
1003 }
1004
1005 int getNumIterImpl() override
1006 {
1007 HYPRE_Int num_iter;
1008 auto error =
1009 HYPRE_SStructBiCGSTABGetNumIterations( _solver, &num_iter );
1010 this->checkHypreError( error );
1011 return num_iter;
1012 }
1013
1015 {
1016 HYPRE_Real norm;
1017 auto error =
1018 HYPRE_SStructBiCGSTABGetFinalRelativeResidualNorm( _solver, &norm );
1019 this->checkHypreError( error );
1020 return norm;
1021 }
1022
1025 preconditioner ) override
1026 {
1027 auto error = HYPRE_SStructBiCGSTABSetPrecond(
1028 _solver, preconditioner.getHypreSolveFunction(),
1029 preconditioner.getHypreSetupFunction(),
1030 preconditioner.getHypreSolver() );
1031 this->checkHypreError( error );
1032 }
1033
1034 private:
1035 HYPRE_SStructSolver _solver;
1036 using base_type::_A;
1037 using base_type::_b;
1038 using base_type::_x;
1039};
1040
1041//---------------------------------------------------------------------------//
1043template <class Scalar, class EntityType, class MemorySpace>
1045 : public HypreSemiStructuredSolver<Scalar, EntityType, MemorySpace>
1046{
1047 public:
1052 template <class ArrayLayout_t>
1053 HypreSemiStructDiagonal( const ArrayLayout_t& layout,
1054 const bool is_preconditioner = false,
1055 int n_vars = 3 )
1056 : base_type( layout, n_vars, is_preconditioner )
1057 {
1058 if ( !is_preconditioner )
1059 throw std::logic_error(
1060 "Diagonal preconditioner cannot be used as a solver" );
1061 }
1062
1063 HYPRE_SStructSolver getHypreSolver() const override { return nullptr; }
1064 HYPRE_PtrToSStructSolverFcn getHypreSetupFunction() const override
1065 {
1066 return HYPRE_SStructDiagScaleSetup;
1067 }
1068 HYPRE_PtrToSStructSolverFcn getHypreSolveFunction() const override
1069 {
1070 return HYPRE_SStructDiagScale;
1071 }
1072
1073 protected:
1074 void setToleranceImpl( const double ) override
1075 {
1076 throw std::logic_error(
1077 "Diagonal preconditioner cannot be used as a solver" );
1078 }
1079
1080 void setMaxIterImpl( const int ) override
1081 {
1082 throw std::logic_error(
1083 "Diagonal preconditioner cannot be used as a solver" );
1084 }
1085
1086 void setPrintLevelImpl( const int ) override
1087 {
1088 throw std::logic_error(
1089 "Diagonal preconditioner cannot be used as a solver" );
1090 }
1091
1092 void setupImpl() override
1093 {
1094 throw std::logic_error(
1095 "Diagonal preconditioner cannot be used as a solver" );
1096 }
1097
1098 void solveImpl() override
1099 {
1100 throw std::logic_error(
1101 "Diagonal preconditioner cannot be used as a solver" );
1102 }
1103
1104 int getNumIterImpl() override
1105 {
1106 throw std::logic_error(
1107 "Diagonal preconditioner cannot be used as a solver" );
1108 }
1109
1111 {
1112 throw std::logic_error(
1113 "Diagonal preconditioner cannot be used as a solver" );
1114 }
1115
1118 override
1119 {
1120 throw std::logic_error(
1121 "Diagonal preconditioner does not support preconditioning." );
1122 }
1123};
1124
1125//---------------------------------------------------------------------------//
1126// Builders
1127//---------------------------------------------------------------------------//
1129template <class Scalar, class MemorySpace, class ArrayLayout_t>
1130std::shared_ptr<HypreSemiStructPCG<Scalar, typename ArrayLayout_t::entity_type,
1131 MemorySpace>>
1132createHypreSemiStructPCG( const ArrayLayout_t& layout,
1133 const bool is_preconditioner = false, int n_vars = 3 )
1134{
1136 "Must use an array layout" );
1137 return std::make_shared<HypreSemiStructPCG<
1138 Scalar, typename ArrayLayout_t::entity_type, MemorySpace>>(
1139 layout, n_vars, is_preconditioner );
1140}
1141
1143template <class Scalar, class MemorySpace, class ArrayLayout_t>
1144std::shared_ptr<HypreSemiStructGMRES<
1145 Scalar, typename ArrayLayout_t::entity_type, MemorySpace>>
1146createHypreSemiStructGMRES( const ArrayLayout_t& layout,
1147 const bool is_preconditioner = false,
1148 int n_vars = 3 )
1149{
1151 "Must use an array layout" );
1152 return std::make_shared<HypreSemiStructGMRES<
1153 Scalar, typename ArrayLayout_t::entity_type, MemorySpace>>(
1154 layout, n_vars, is_preconditioner );
1155}
1156
1158template <class Scalar, class MemorySpace, class ArrayLayout_t>
1159std::shared_ptr<HypreSemiStructBiCGSTAB<
1160 Scalar, typename ArrayLayout_t::entity_type, MemorySpace>>
1161createHypreSemiStructBiCGSTAB( const ArrayLayout_t& layout,
1162 const bool is_preconditioner = false,
1163 int n_vars = 3 )
1164{
1166 "Must use an array layout" );
1167 return std::make_shared<HypreSemiStructBiCGSTAB<
1168 Scalar, typename ArrayLayout_t::entity_type, MemorySpace>>(
1169 layout, is_preconditioner, n_vars );
1170}
1171
1173template <class Scalar, class MemorySpace, class ArrayLayout_t>
1174std::shared_ptr<HypreSemiStructDiagonal<
1175 Scalar, typename ArrayLayout_t::entity_type, MemorySpace>>
1176createHypreSemiStructDiagonal( const ArrayLayout_t& layout,
1177 const bool is_preconditioner = false,
1178 int n_vars = 3 )
1179{
1181 "Must use an array layout" );
1182 return std::make_shared<HypreSemiStructDiagonal<
1183 Scalar, typename ArrayLayout_t::entity_type, MemorySpace>>(
1184 layout, is_preconditioner, n_vars );
1185}
1186
1187//---------------------------------------------------------------------------//
1188// Factory
1189//---------------------------------------------------------------------------//
1198template <class Scalar, class MemorySpace, class ArrayLayout_t>
1199std::shared_ptr<HypreSemiStructuredSolver<
1200 Scalar, typename ArrayLayout_t::entity_type, MemorySpace>>
1201createHypreSemiStructuredSolver( const std::string& solver_type,
1202 const ArrayLayout_t& layout,
1203 const bool is_preconditioner = false,
1204 int n_vars = 3 )
1205{
1207 "Must use an array layout" );
1208
1209 if ( "PCG" == solver_type )
1211 layout, is_preconditioner, n_vars );
1212 else if ( "GMRES" == solver_type )
1214 layout, is_preconditioner, n_vars );
1215 else if ( "BiCGSTAB" == solver_type )
1217 layout, is_preconditioner, n_vars );
1218 else if ( "Diagonal" == solver_type )
1220 layout, is_preconditioner, n_vars );
1221 else
1222 throw std::runtime_error( "Invalid solver type" );
1223}
1224
1225//---------------------------------------------------------------------------//
1226
1227} // namespace Grid
1228} // namespace Cabana
1229
1230#endif // end CABANA_GRID_HypreSemiStRUCTUREDSOLVER_HPP
Grid field arrays.
std::shared_ptr< HypreSemiStructPCG< Scalar, typename ArrayLayout_t::entity_type, MemorySpace > > createHypreSemiStructPCG(const ArrayLayout_t &layout, const bool is_preconditioner=false, int n_vars=3)
Create a HYPRE PCG semi-structured solver.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1132
std::shared_ptr< HypreSemiStructuredSolver< Scalar, typename ArrayLayout_t::entity_type, MemorySpace > > createHypreSemiStructuredSolver(const std::string &solver_type, const ArrayLayout_t &layout, const bool is_preconditioner=false, int n_vars=3)
Create a HYPRE semi-structured solver.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1201
std::shared_ptr< HypreSemiStructBiCGSTAB< Scalar, typename ArrayLayout_t::entity_type, MemorySpace > > createHypreSemiStructBiCGSTAB(const ArrayLayout_t &layout, const bool is_preconditioner=false, int n_vars=3)
Create a HYPRE BiCGSTAB semi-structured solver.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1161
std::shared_ptr< HypreSemiStructGMRES< Scalar, typename ArrayLayout_t::entity_type, MemorySpace > > createHypreSemiStructGMRES(const ArrayLayout_t &layout, const bool is_preconditioner=false, int n_vars=3)
Create a HYPRE GMRES semi-structured solver.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1146
std::shared_ptr< HypreSemiStructDiagonal< Scalar, typename ArrayLayout_t::entity_type, MemorySpace > > createHypreSemiStructDiagonal(const ArrayLayout_t &layout, const bool is_preconditioner=false, int n_vars=3)
Create a HYPRE Diagonal semi-structured solver.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1176
HYPRE memory space handling.
Logical grid indexing.
KOKKOS_INLINE_FUNCTION auto createSubview(const ViewType &view, const IndexSpace< 1 > &index_space) -> decltype(Kokkos::subview(view, index_space.range(0)))
Given a view create a subview over the given index space.
Definition Cabana_Grid_IndexSpace.hpp:369
Kokkos::View< Scalar *, Params... > createView(const std::string &label, const IndexSpace< 1 > &index_space)
Given an index space create a view over the extent of that index space.
Definition Cabana_Grid_IndexSpace.hpp:235
Grid type tags.
BiCGSTAB solver.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:925
void solveImpl() override
Solver implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:999
double getFinalRelativeResidualNormImpl() override
Get the relative residual norm achieved on the last solve.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1014
HYPRE_PtrToSStructSolverFcn getHypreSetupFunction() const override
Get the preconditioner setup function.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:965
void setupImpl() override
Setup implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:993
void setLogging(const int logging)
Set the amount of logging to do.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:958
HypreSemiStructBiCGSTAB(const ArrayLayout_t &layout, const bool is_preconditioner=false, int n_vars=3)
Constructor.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:932
HYPRE_SStructSolver getHypreSolver() const override
Get the preconditioner.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:964
HypreSemiStructuredSolver< Scalar, EntityType, MemorySpace > base_type
Base HYPRE semi-structured solver type.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:928
int getNumIterImpl() override
Get the number of iterations taken on the last solve.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1005
void setPrintLevelImpl(const int print_level) override
Set the output level.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:987
void setMaxIterImpl(const int max_iter) override
Set maximum iteration implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:981
HYPRE_PtrToSStructSolverFcn getHypreSolveFunction() const override
Get the preconditioner solve function.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:969
void setPreconditionerImpl(const HypreSemiStructuredSolver< Scalar, EntityType, MemorySpace > &preconditioner) override
Set a preconditioner.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1023
void setAbsoluteTol(const double tol)
Set the absolute tolerance.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:951
void setToleranceImpl(const double tol) override
Set convergence tolerance implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:975
Diagonal preconditioner.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1046
HypreSemiStructuredSolver< Scalar, EntityType, MemorySpace > base_type
Base HYPRE semi-structured solver type.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1049
void setMaxIterImpl(const int) override
Set maximum iteration implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1080
int getNumIterImpl() override
Get the number of iterations taken on the last solve.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1104
HYPRE_PtrToSStructSolverFcn getHypreSolveFunction() const override
Get the preconditioner solve function.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1068
void setPrintLevelImpl(const int) override
Set the output level.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1086
void setToleranceImpl(const double) override
Set convergence tolerance implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1074
void solveImpl() override
Solver implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1098
void setPreconditionerImpl(const HypreSemiStructuredSolver< Scalar, EntityType, MemorySpace > &) override
Set a preconditioner.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1116
HypreSemiStructDiagonal(const ArrayLayout_t &layout, const bool is_preconditioner=false, int n_vars=3)
Constructor.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1053
double getFinalRelativeResidualNormImpl() override
Get the relative residual norm achieved on the last solve.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1110
HYPRE_SStructSolver getHypreSolver() const override
Get the preconditioner.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1063
void setupImpl() override
Setup implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1092
HYPRE_PtrToSStructSolverFcn getHypreSetupFunction() const override
Get the preconditioner setup function.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1064
GMRES solver.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:799
void setPrintLevelImpl(const int print_level) override
Set the output level.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:867
HypreSemiStructGMRES(const ArrayLayout_t &layout, int n_vars, const bool is_preconditioner=false)
Constructor.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:806
void setMaxIterImpl(const int max_iter) override
Set maximum iteration implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:861
void setToleranceImpl(const double tol) override
Set convergence tolerance implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:855
HypreSemiStructuredSolver< Scalar, EntityType, MemorySpace > base_type
Base HYPRE semi-structured solver type.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:802
int getNumIterImpl() override
Get the number of iterations taken on the last solve.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:885
HYPRE_PtrToSStructSolverFcn getHypreSolveFunction() const override
Get the preconditioner solve function.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:849
double getFinalRelativeResidualNormImpl() override
Get the relative residual norm achieved on the last solve.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:893
void setKDim(const int k_dim)
Set the max size of the Krylov space.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:831
void solveImpl() override
Solver implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:879
void setupImpl() override
Setup implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:873
HYPRE_PtrToSStructSolverFcn getHypreSetupFunction() const override
Get the preconditioner setup function.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:845
HYPRE_SStructSolver getHypreSolver() const override
Get the preconditioner.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:844
void setLogging(const int logging)
Set the amount of logging to do.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:838
void setPreconditionerImpl(const HypreSemiStructuredSolver< Scalar, EntityType, MemorySpace > &preconditioner) override
Set a preconditioner.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:902
void setAbsoluteTol(const double tol)
Set the absolute tolerance.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:824
PCG solver.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:670
HypreSemiStructPCG(const ArrayLayout_t &layout, int n_vars, const bool is_preconditioner=false)
Constructor.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:677
HYPRE_PtrToSStructSolverFcn getHypreSolveFunction() const override
Get the preconditioner solve function.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:723
void setLogging(const int logging)
Set the amount of logging to do.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:712
double getFinalRelativeResidualNormImpl() override
Get the relative residual norm achieved on the last solve.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:767
HYPRE_PtrToSStructSolverFcn getHypreSetupFunction() const override
Get the preconditioner setup function.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:719
void setPreconditionerImpl(const HypreSemiStructuredSolver< Scalar, EntityType, MemorySpace > &preconditioner) override
Set a preconditioner.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:776
void solveImpl() override
Solver implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:753
void setPrintLevelImpl(const int print_level) override
Set the output level.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:741
void setRelChange(const int rel_change)
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:705
void setMaxIterImpl(const int max_iter) override
Set maximum iteration implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:735
HYPRE_SStructSolver getHypreSolver() const override
Get the preconditioner.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:718
void setupImpl() override
Setup implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:747
void setAbsoluteTol(const double tol)
Set the absolute tolerance.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:697
HypreSemiStructuredSolver< Scalar, EntityType, MemorySpace > base_type
Base HYPRE semi-structured solver type.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:673
int getNumIterImpl() override
Get the number of iterations taken on the last solve.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:759
void setToleranceImpl(const double tol) override
Set convergence tolerance implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:729
Hypre semi-structured solver interface for scalar fields.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:52
virtual void setToleranceImpl(const double tol)=0
Set convergence tolerance implementation.
void setup()
Setup the problem.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:476
void printLHS(const char *prefix)
Print the hypre LHS to output file.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:431
const int object_type
Object Type for SStruct.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:61
void setPrintLevel(const int print_level)
Set the output level.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:452
int getNumIter()
Get the number of iterations taken on the last solve.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:587
void setPreconditioner(const std::shared_ptr< HypreSemiStructuredSolver< Scalar, EntityType, MemorySpace > > &preconditioner)
Set a preconditioner.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:459
virtual HYPRE_PtrToSStructSolverFcn getHypreSetupFunction() const =0
Get the preconditioner setup function.
void solve(const Array_t &b, Array_t &x, int n_vars=3)
Solve the problem Ax = b for x.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:495
void setMaxIter(const int max_iter)
Set maximum iteration implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:449
virtual int getNumIterImpl()=0
Get the number of iterations taken on the last solve.
HYPRE_SStructMatrix _A
Matrix for the problem Ax = b.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:645
virtual double getFinalRelativeResidualNormImpl()=0
Get the relative residual norm achieved on the last solve.
virtual void setPreconditionerImpl(const HypreSemiStructuredSolver< Scalar, EntityType, MemorySpace > &preconditioner)=0
Set a preconditioner.
double getFinalRelativeResidualNorm()
Get the relative residual norm achieved on the last solve.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:590
void setMatrixValues(const Array_t &values, int v_x, int v_h)
Set the matrix values.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:357
void setTolerance(const double tol)
Set convergence tolerance implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:446
virtual void solveImpl()=0
Solver implementation.
virtual void setMaxIterImpl(const int max_iter)=0
Set maximum iteration implementation.
HypreSemiStructuredSolver(const ArrayLayout_t &layout, int n_vars, const bool is_preconditioner=false)
Hypre memory space compatibility check.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:74
MemorySpace memory_space
Kokkos memory space..
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:57
virtual void setPrintLevelImpl(const int print_level)=0
Set the output level.
void setSolverGraph(int n_vars)
Set the solver graph.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:301
void printRHS(const char *prefix)
Print the hypre RHS to output file.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:440
EntityType entity_type
Entity type.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:55
void checkHypreError(const int error) const
Check a hypre error.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:630
virtual void setupImpl()=0
Setup implementation.
void createMatrixStencil(int NumSpaceDim, int var=0, int n_vars=3, std::vector< unsigned > stencil_length={ 7, 7, 7 })
Create the operator stencil to be filled by setMatrixStencil.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:239
void setMatrixStencil(const std::vector< std::array< int, NumSpaceDim > > &stencil, int var=0, int dep=0)
Set the operator stencil.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:275
HYPRE_SStructVector _x
Solution to the problem Ax = b.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:649
bool isPreconditioner() const
Return if this solver is a preconditioner.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:227
virtual HYPRE_PtrToSStructSolverFcn getHypreSolveFunction() const =0
Get the preconditioner solve function.
void printMatrix(const char *prefix)
Print the hypre matrix to output file.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:422
Scalar value_type
Scalar value type.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:59
HYPRE_SStructVector _b
Forcing term for the problem Ax = b.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:647
virtual HYPRE_SStructSolver getHypreSolver() const =0
Get the preconditioner.
Structured index space.
Definition Cabana_Grid_IndexSpace.hpp:37
Core: particle data structures and algorithms.
Definition Cabana_AoSoA.hpp:36
Global index tag.
Definition Cabana_Grid_Types.hpp:215
Hypre device compatibility check.
Definition Cabana_Grid_Hypre.hpp:39
Local index tag.
Definition Cabana_Grid_Types.hpp:208
Owned decomposition tag.
Definition Cabana_Grid_Types.hpp:190
Array static type checker.
Definition Cabana_Grid_Array.hpp:160
Definition Cabana_Grid_Array.hpp:322