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 must 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 must 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 "Cabana::Grid::HypreSemiStructuredSolver::setMatrixValues: "
384 "Number of matrix values does not match stencil size" );
385
386 // Spatial dimension.
387 const std::size_t num_space_dim = Array_t::num_space_dim;
388
389 int part = 0;
390
391 // Copy the matrix entries into HYPRE. The HYPRE layout is fixed as
392 // layout-right.
393 auto owned_space = values.layout()->indexSpace( Own(), Local() );
394 std::array<long, num_space_dim + 1> reorder_size;
395 for ( std::size_t d = 0; d < num_space_dim; ++d )
396 {
397 reorder_size[d] = owned_space.extent( d );
398 }
399
400 reorder_size.back() = index_size;
401 IndexSpace<num_space_dim + 1> reorder_space( reorder_size );
402 auto a_values =
404 "a_values", reorder_space );
405
406 auto values_subv = createSubview( values.view(), owned_space );
407 Kokkos::deep_copy( a_values, values_subv );
408
409 // Insert values into the HYPRE matrix.
410 std::vector<HYPRE_Int> indices( index_size );
411 int start = _stencil_index[v_h][v_x];
412 std::iota( indices.begin(), indices.end(), start );
413 auto error = HYPRE_SStructMatrixSetBoxValues(
414 _A, part, _lower.data(), _upper.data(), v_h, indices.size(),
415 indices.data(), a_values.data() );
416 checkHypreError( error );
417 }
418
423 void printMatrix( const char* prefix )
424 {
425 HYPRE_SStructMatrixPrint( prefix, _A, 0 );
426 }
427
432 void printLHS( const char* prefix )
433 {
434 HYPRE_SStructVectorPrint( prefix, _x, 0 );
435 }
436
441 void printRHS( const char* prefix )
442 {
443 HYPRE_SStructVectorPrint( prefix, _b, 0 );
444 }
445
447 void setTolerance( const double tol ) { this->setToleranceImpl( tol ); }
448
450 void setMaxIter( const int max_iter ) { this->setMaxIterImpl( max_iter ); }
451
453 void setPrintLevel( const int print_level )
454 {
455 this->setPrintLevelImpl( print_level );
456 }
457
459 void
461 Scalar, EntityType, MemorySpace>>& preconditioner )
462 {
463 // This function is only valid for non-preconditioners.
464 if ( _is_preconditioner )
465 throw std::logic_error(
466 "Cannot call setPreconditioner() on a preconditioner" );
467
468 // Only a preconditioner can be used as a preconditioner.
469 if ( !preconditioner->isPreconditioner() )
470 throw std::logic_error( "Not a preconditioner" );
471
472 _preconditioner = preconditioner;
473 this->setPreconditionerImpl( *_preconditioner );
474 }
475
477 void setup()
478 {
479 // This function is only valid for non-preconditioners.
480 if ( _is_preconditioner )
481 throw std::logic_error( "Cannot call setup() on preconditioners" );
482
483 auto error = HYPRE_SStructMatrixAssemble( _A );
484 checkHypreError( error );
485
486 this->setupImpl();
487 }
488
495 template <class Array_t>
496 void solve( const Array_t& b, Array_t& x, int n_vars = 3 )
497 {
498 Kokkos::Profiling::ScopedRegion region(
499 "Cabana::Grid::HypreSemiStructuredSolver::solve" );
500
501 static_assert( is_array<Array_t>::value, "Must use an array" );
502 static_assert(
503 std::is_same<typename Array_t::entity_type, entity_type>::value,
504 "Array entity type must match solver entity type" );
505 static_assert(
506 std::is_same<typename Array_t::memory_space, MemorySpace>::value,
507 "Array device type and solver device type are different." );
508
509 static_assert(
510 std::is_same<typename Array_t::value_type, value_type>::value,
511 "Array value type and solver value type are different." );
512
513 // This function is only valid for non-preconditioners.
514 if ( _is_preconditioner )
515 throw std::logic_error( "Cannot call solve() on preconditioners" );
516
517 // Spatial dimension.
518 const std::size_t num_space_dim = Array_t::num_space_dim;
519
520 int part = 0;
521
522 // Copy the RHS into HYPRE. The HYPRE layout is fixed as layout-right.
523 auto owned_space = b.layout()->indexSpace( Own(), Local() );
524 std::array<long, num_space_dim + 1> reorder_min;
525 std::array<long, num_space_dim + 1> reorder_max;
526 for ( std::size_t d = 0; d < num_space_dim; ++d )
527 {
528 reorder_min[d] = owned_space.min( d );
529 reorder_max[d] = owned_space.max( d );
530 }
531
532 // Insert b values into the HYPRE vector.
533 // The process of creating the view and then deep copying each
534 // variable is functional, but we should avoid this process
535 // for performance if possible
536 int error;
537 for ( int var = 0; var < n_vars; ++var )
538 {
539 reorder_min.back() = var;
540 reorder_max.back() = var + 1;
541
542 IndexSpace<num_space_dim + 1> reorder_space( reorder_min,
543 reorder_max );
544 auto b_values =
546 "vector_values", reorder_space );
547 // Extract one variable at at time.
548 auto b_subv = createSubview( b.view(), reorder_space );
549
550 Kokkos::deep_copy( b_values, b_subv );
551 error = HYPRE_SStructVectorSetBoxValues(
552 _b, part, _lower.data(), _upper.data(), var, b_values.data() );
553 checkHypreError( error );
554 }
555
556 error = HYPRE_SStructVectorAssemble( _b );
557 checkHypreError( error );
558
559 // Solve the problem
560 this->solveImpl();
561
562 // Extract the solution from the LHS
563 for ( int var = 0; var < n_vars; ++var )
564 {
565 reorder_min.back() = var;
566 reorder_max.back() = var + 1;
567
568 IndexSpace<num_space_dim + 1> reorder_space( reorder_min,
569 reorder_max );
570 auto x_values =
572 "vector_values", reorder_space );
573
574 // Extract one variable at at time.
575 // Use a pair here to retain the view rank.
576
577 error = HYPRE_SStructVectorGetBoxValues(
578 _x, part, _lower.data(), _upper.data(), var, x_values.data() );
579 checkHypreError( error );
580
581 // Copy the HYPRE solution to the LHS.
582 auto x_subv = createSubview( x.view(), reorder_space );
583 Kokkos::deep_copy( x_subv, x_values );
584 }
585 }
586
588 int getNumIter() { return this->getNumIterImpl(); }
589
592 {
594 }
595
597 virtual HYPRE_SStructSolver getHypreSolver() const = 0;
599 virtual HYPRE_PtrToSStructSolverFcn getHypreSetupFunction() const = 0;
601 virtual HYPRE_PtrToSStructSolverFcn getHypreSolveFunction() const = 0;
602
603 protected:
605 virtual void setToleranceImpl( const double tol ) = 0;
606
608 virtual void setMaxIterImpl( const int max_iter ) = 0;
609
611 virtual void setPrintLevelImpl( const int print_level ) = 0;
612
614 virtual void setupImpl() = 0;
615
617 virtual void solveImpl() = 0;
618
620 virtual int getNumIterImpl() = 0;
621
624
628 preconditioner ) = 0;
629
631 void checkHypreError( const int error ) const
632 {
633 if ( error > 0 )
634 {
635 char error_msg[256];
636 HYPRE_DescribeError( error, error_msg );
637 std::stringstream out;
638 out << "HYPRE semi-structured solver error: ";
639 out << error << " " << error_msg;
640 HYPRE_ClearError( error );
641 throw std::runtime_error( out.str() );
642 }
643 }
644
646 HYPRE_SStructMatrix _A;
648 HYPRE_SStructVector _b;
650 HYPRE_SStructVector _x;
651
652 private:
653 MPI_Comm _comm;
654 bool _is_preconditioner;
655 HYPRE_SStructGrid _grid;
656 std::vector<HYPRE_Int> _lower;
657 std::vector<HYPRE_Int> _upper;
658 std::vector<HYPRE_SStructStencil> _stencils;
659 HYPRE_SStructGraph _graph;
660 std::vector<unsigned> _stencil_size;
661 std::vector<std::vector<unsigned>> _stencil_index;
662 std::shared_ptr<HypreSemiStructuredSolver<Scalar, EntityType, MemorySpace>>
663 _preconditioner;
664};
665
666//---------------------------------------------------------------------------//
668template <class Scalar, class EntityType, class MemorySpace>
670 : public HypreSemiStructuredSolver<Scalar, EntityType, MemorySpace>
671{
672 public:
674 using base_type =
677 template <class ArrayLayout_t>
678 HypreSemiStructPCG( const ArrayLayout_t& layout, int n_vars,
679 const bool is_preconditioner = false )
680 : base_type( layout, n_vars, is_preconditioner )
681 {
682 if ( is_preconditioner )
683 throw std::logic_error(
684 "HYPRE PCG cannot be used as a preconditioner" );
685
686 auto error = HYPRE_SStructPCGCreate(
687 layout.localGrid()->globalGrid().comm(), &_solver );
688 this->checkHypreError( error );
689
690 HYPRE_SStructPCGSetTwoNorm( _solver, 1 );
691 }
692
693 ~HypreSemiStructPCG() { HYPRE_SStructPCGDestroy( _solver ); }
694
695 // PCG SETTINGS
696
698 void setAbsoluteTol( const double tol )
699 {
700 auto error = HYPRE_SStructPCGSetAbsoluteTol( _solver, tol );
701 this->checkHypreError( error );
702 }
703
706 void setRelChange( const int rel_change )
707 {
708 auto error = HYPRE_SStructPCGSetRelChange( _solver, rel_change );
709 this->checkHypreError( error );
710 }
711
713 void setLogging( const int logging )
714 {
715 auto error = HYPRE_SStructPCGSetLogging( _solver, logging );
716 this->checkHypreError( error );
717 }
718
719 HYPRE_SStructSolver getHypreSolver() const override { return _solver; }
720 HYPRE_PtrToSStructSolverFcn getHypreSetupFunction() const override
721 {
722 return HYPRE_SStructPCGSetup;
723 }
724 HYPRE_PtrToSStructSolverFcn getHypreSolveFunction() const override
725 {
726 return HYPRE_SStructPCGSolve;
727 }
728
729 protected:
730 void setToleranceImpl( const double tol ) override
731 {
732 auto error = HYPRE_SStructPCGSetTol( _solver, tol );
733 this->checkHypreError( error );
734 }
735
736 void setMaxIterImpl( const int max_iter ) override
737 {
738 auto error = HYPRE_SStructPCGSetMaxIter( _solver, max_iter );
739 this->checkHypreError( error );
740 }
741
742 void setPrintLevelImpl( const int print_level ) override
743 {
744 auto error = HYPRE_SStructPCGSetPrintLevel( _solver, print_level );
745 this->checkHypreError( error );
746 }
747
748 void setupImpl() override
749 {
750 auto error = HYPRE_SStructPCGSetup( _solver, _A, _b, _x );
751 this->checkHypreError( error );
752 }
753
754 void solveImpl() override
755 {
756 auto error = HYPRE_SStructPCGSolve( _solver, _A, _b, _x );
757 this->checkHypreError( error );
758 }
759
760 int getNumIterImpl() override
761 {
762 HYPRE_Int num_iter;
763 auto error = HYPRE_SStructPCGGetNumIterations( _solver, &num_iter );
764 this->checkHypreError( error );
765 return num_iter;
766 }
767
769 {
770 HYPRE_Real norm;
771 auto error =
772 HYPRE_SStructPCGGetFinalRelativeResidualNorm( _solver, &norm );
773 this->checkHypreError( error );
774 return norm;
775 }
776
779 preconditioner ) override
780 {
781 auto error = HYPRE_SStructPCGSetPrecond(
782 _solver, preconditioner.getHypreSolveFunction(),
783 preconditioner.getHypreSetupFunction(),
784 preconditioner.getHypreSolver() );
785 this->checkHypreError( error );
786 }
787
788 private:
789 HYPRE_SStructSolver _solver;
790 using base_type::_A;
791 using base_type::_b;
792 using base_type::_x;
793};
794
795//---------------------------------------------------------------------------//
797template <class Scalar, class EntityType, class MemorySpace>
799 : public HypreSemiStructuredSolver<Scalar, EntityType, MemorySpace>
800{
801 public:
803 using base_type =
806 template <class ArrayLayout_t>
807 HypreSemiStructGMRES( const ArrayLayout_t& layout, int n_vars,
808 const bool is_preconditioner = false )
809 : base_type( layout, n_vars, is_preconditioner )
810 {
811 if ( is_preconditioner )
812 throw std::logic_error(
813 "HYPRE GMRES cannot be used as a preconditioner" );
814
815 auto error = HYPRE_SStructGMRESCreate(
816 layout.localGrid()->globalGrid().comm(), &_solver );
817 this->checkHypreError( error );
818 }
819
820 ~HypreSemiStructGMRES() { HYPRE_SStructGMRESDestroy( _solver ); }
821
822 // GMRES SETTINGS
823
825 void setAbsoluteTol( const double tol )
826 {
827 auto error = HYPRE_SStructGMRESSetAbsoluteTol( _solver, tol );
828 this->checkHypreError( error );
829 }
830
832 void setKDim( const int k_dim )
833 {
834 auto error = HYPRE_SStructGMRESSetKDim( _solver, k_dim );
835 this->checkHypreError( error );
836 }
837
839 void setLogging( const int logging )
840 {
841 auto error = HYPRE_SStructGMRESSetLogging( _solver, logging );
842 this->checkHypreError( error );
843 }
844
845 HYPRE_SStructSolver getHypreSolver() const override { return _solver; }
846 HYPRE_PtrToSStructSolverFcn getHypreSetupFunction() const override
847 {
848 return HYPRE_SStructGMRESSetup;
849 }
850 HYPRE_PtrToSStructSolverFcn getHypreSolveFunction() const override
851 {
852 return HYPRE_SStructGMRESSolve;
853 }
854
855 protected:
856 void setToleranceImpl( const double tol ) override
857 {
858 auto error = HYPRE_SStructGMRESSetTol( _solver, tol );
859 this->checkHypreError( error );
860 }
861
862 void setMaxIterImpl( const int max_iter ) override
863 {
864 auto error = HYPRE_SStructGMRESSetMaxIter( _solver, max_iter );
865 this->checkHypreError( error );
866 }
867
868 void setPrintLevelImpl( const int print_level ) override
869 {
870 auto error = HYPRE_SStructGMRESSetPrintLevel( _solver, print_level );
871 this->checkHypreError( error );
872 }
873
874 void setupImpl() override
875 {
876 auto error = HYPRE_SStructGMRESSetup( _solver, _A, _b, _x );
877 this->checkHypreError( error );
878 }
879
880 void solveImpl() override
881 {
882 auto error = HYPRE_SStructGMRESSolve( _solver, _A, _b, _x );
883 this->checkHypreError( error );
884 }
885
886 int getNumIterImpl() override
887 {
888 HYPRE_Int num_iter;
889 auto error = HYPRE_SStructGMRESGetNumIterations( _solver, &num_iter );
890 this->checkHypreError( error );
891 return num_iter;
892 }
893
895 {
896 HYPRE_Real norm;
897 auto error =
898 HYPRE_SStructGMRESGetFinalRelativeResidualNorm( _solver, &norm );
899 this->checkHypreError( error );
900 return norm;
901 }
902
905 preconditioner ) override
906 {
907 auto error = HYPRE_SStructGMRESSetPrecond(
908 _solver, preconditioner.getHypreSolveFunction(),
909 preconditioner.getHypreSetupFunction(),
910 preconditioner.getHypreSolver() );
911 this->checkHypreError( error );
912 }
913
914 private:
915 HYPRE_SStructSolver _solver;
916 using base_type::_A;
917 using base_type::_b;
918 using base_type::_x;
919};
920
921//---------------------------------------------------------------------------//
923template <class Scalar, class EntityType, class MemorySpace>
925 : public HypreSemiStructuredSolver<Scalar, EntityType, MemorySpace>
926{
927 public:
929 using base_type =
932 template <class ArrayLayout_t>
933 HypreSemiStructBiCGSTAB( const ArrayLayout_t& layout,
934 const bool is_preconditioner = false,
935 int n_vars = 3 )
936 : base_type( layout, n_vars, is_preconditioner )
937 {
938 if ( is_preconditioner )
939 throw std::logic_error(
940 "HYPRE BiCGSTAB cannot be used as a preconditioner" );
941
942 auto error = HYPRE_SStructBiCGSTABCreate(
943 layout.localGrid()->globalGrid().comm(), &_solver );
944 this->checkHypreError( error );
945 }
946
947 ~HypreSemiStructBiCGSTAB() { HYPRE_SStructBiCGSTABDestroy( _solver ); }
948
949 // BiCGSTAB SETTINGS
950
952 void setAbsoluteTol( const double tol )
953 {
954 auto error = HYPRE_SStructBiCGSTABSetAbsoluteTol( _solver, tol );
955 this->checkHypreError( error );
956 }
957
959 void setLogging( const int logging )
960 {
961 auto error = HYPRE_SStructBiCGSTABSetLogging( _solver, logging );
962 this->checkHypreError( error );
963 }
964
965 HYPRE_SStructSolver getHypreSolver() const override { return _solver; }
966 HYPRE_PtrToSStructSolverFcn getHypreSetupFunction() const override
967 {
968 return HYPRE_SStructBiCGSTABSetup;
969 }
970 HYPRE_PtrToSStructSolverFcn getHypreSolveFunction() const override
971 {
972 return HYPRE_SStructBiCGSTABSolve;
973 }
974
975 protected:
976 void setToleranceImpl( const double tol ) override
977 {
978 auto error = HYPRE_SStructBiCGSTABSetTol( _solver, tol );
979 this->checkHypreError( error );
980 }
981
982 void setMaxIterImpl( const int max_iter ) override
983 {
984 auto error = HYPRE_SStructBiCGSTABSetMaxIter( _solver, max_iter );
985 this->checkHypreError( error );
986 }
987
988 void setPrintLevelImpl( const int print_level ) override
989 {
990 auto error = HYPRE_SStructBiCGSTABSetPrintLevel( _solver, print_level );
991 this->checkHypreError( error );
992 }
993
994 void setupImpl() override
995 {
996 auto error = HYPRE_SStructBiCGSTABSetup( _solver, _A, _b, _x );
997 this->checkHypreError( error );
998 }
999
1000 void solveImpl() override
1001 {
1002 auto error = HYPRE_SStructBiCGSTABSolve( _solver, _A, _b, _x );
1003 this->checkHypreError( error );
1004 }
1005
1006 int getNumIterImpl() override
1007 {
1008 HYPRE_Int num_iter;
1009 auto error =
1010 HYPRE_SStructBiCGSTABGetNumIterations( _solver, &num_iter );
1011 this->checkHypreError( error );
1012 return num_iter;
1013 }
1014
1016 {
1017 HYPRE_Real norm;
1018 auto error =
1019 HYPRE_SStructBiCGSTABGetFinalRelativeResidualNorm( _solver, &norm );
1020 this->checkHypreError( error );
1021 return norm;
1022 }
1023
1026 preconditioner ) override
1027 {
1028 auto error = HYPRE_SStructBiCGSTABSetPrecond(
1029 _solver, preconditioner.getHypreSolveFunction(),
1030 preconditioner.getHypreSetupFunction(),
1031 preconditioner.getHypreSolver() );
1032 this->checkHypreError( error );
1033 }
1034
1035 private:
1036 HYPRE_SStructSolver _solver;
1037 using base_type::_A;
1038 using base_type::_b;
1039 using base_type::_x;
1040};
1041
1042//---------------------------------------------------------------------------//
1044template <class Scalar, class EntityType, class MemorySpace>
1046 : public HypreSemiStructuredSolver<Scalar, EntityType, MemorySpace>
1047{
1048 public:
1053 template <class ArrayLayout_t>
1054 HypreSemiStructDiagonal( const ArrayLayout_t& layout,
1055 const bool is_preconditioner = false,
1056 int n_vars = 3 )
1057 : base_type( layout, n_vars, is_preconditioner )
1058 {
1059 if ( !is_preconditioner )
1060 throw std::logic_error(
1061 "Diagonal preconditioner cannot be used as a solver" );
1062 }
1063
1064 HYPRE_SStructSolver getHypreSolver() const override { return nullptr; }
1065 HYPRE_PtrToSStructSolverFcn getHypreSetupFunction() const override
1066 {
1067 return HYPRE_SStructDiagScaleSetup;
1068 }
1069 HYPRE_PtrToSStructSolverFcn getHypreSolveFunction() const override
1070 {
1071 return HYPRE_SStructDiagScale;
1072 }
1073
1074 protected:
1075 void setToleranceImpl( const double ) override
1076 {
1077 throw std::logic_error(
1078 "Diagonal preconditioner cannot be used as a solver" );
1079 }
1080
1081 void setMaxIterImpl( const int ) override
1082 {
1083 throw std::logic_error(
1084 "Diagonal preconditioner cannot be used as a solver" );
1085 }
1086
1087 void setPrintLevelImpl( const int ) override
1088 {
1089 throw std::logic_error(
1090 "Diagonal preconditioner cannot be used as a solver" );
1091 }
1092
1093 void setupImpl() override
1094 {
1095 throw std::logic_error(
1096 "Diagonal preconditioner cannot be used as a solver" );
1097 }
1098
1099 void solveImpl() override
1100 {
1101 throw std::logic_error(
1102 "Diagonal preconditioner cannot be used as a solver" );
1103 }
1104
1105 int getNumIterImpl() override
1106 {
1107 throw std::logic_error(
1108 "Diagonal preconditioner cannot be used as a solver" );
1109 }
1110
1112 {
1113 throw std::logic_error(
1114 "Diagonal preconditioner cannot be used as a solver" );
1115 }
1116
1119 override
1120 {
1121 throw std::logic_error(
1122 "Diagonal preconditioner does not support preconditioning." );
1123 }
1124};
1125
1126//---------------------------------------------------------------------------//
1127// Builders
1128//---------------------------------------------------------------------------//
1130template <class Scalar, class MemorySpace, class ArrayLayout_t>
1131std::shared_ptr<HypreSemiStructPCG<Scalar, typename ArrayLayout_t::entity_type,
1132 MemorySpace>>
1133createHypreSemiStructPCG( const ArrayLayout_t& layout,
1134 const bool is_preconditioner = false, int n_vars = 3 )
1135{
1137 "Must use an array layout" );
1138 return std::make_shared<HypreSemiStructPCG<
1139 Scalar, typename ArrayLayout_t::entity_type, MemorySpace>>(
1140 layout, n_vars, is_preconditioner );
1141}
1142
1144template <class Scalar, class MemorySpace, class ArrayLayout_t>
1145std::shared_ptr<HypreSemiStructGMRES<
1146 Scalar, typename ArrayLayout_t::entity_type, MemorySpace>>
1147createHypreSemiStructGMRES( const ArrayLayout_t& layout,
1148 const bool is_preconditioner = false,
1149 int n_vars = 3 )
1150{
1152 "Must use an array layout" );
1153 return std::make_shared<HypreSemiStructGMRES<
1154 Scalar, typename ArrayLayout_t::entity_type, MemorySpace>>(
1155 layout, n_vars, is_preconditioner );
1156}
1157
1159template <class Scalar, class MemorySpace, class ArrayLayout_t>
1160std::shared_ptr<HypreSemiStructBiCGSTAB<
1161 Scalar, typename ArrayLayout_t::entity_type, MemorySpace>>
1162createHypreSemiStructBiCGSTAB( const ArrayLayout_t& layout,
1163 const bool is_preconditioner = false,
1164 int n_vars = 3 )
1165{
1167 "Must use an array layout" );
1168 return std::make_shared<HypreSemiStructBiCGSTAB<
1169 Scalar, typename ArrayLayout_t::entity_type, MemorySpace>>(
1170 layout, is_preconditioner, n_vars );
1171}
1172
1174template <class Scalar, class MemorySpace, class ArrayLayout_t>
1175std::shared_ptr<HypreSemiStructDiagonal<
1176 Scalar, typename ArrayLayout_t::entity_type, MemorySpace>>
1177createHypreSemiStructDiagonal( const ArrayLayout_t& layout,
1178 const bool is_preconditioner = false,
1179 int n_vars = 3 )
1180{
1182 "Must use an array layout" );
1183 return std::make_shared<HypreSemiStructDiagonal<
1184 Scalar, typename ArrayLayout_t::entity_type, MemorySpace>>(
1185 layout, is_preconditioner, n_vars );
1186}
1187
1188//---------------------------------------------------------------------------//
1189// Factory
1190//---------------------------------------------------------------------------//
1199template <class Scalar, class MemorySpace, class ArrayLayout_t>
1200std::shared_ptr<HypreSemiStructuredSolver<
1201 Scalar, typename ArrayLayout_t::entity_type, MemorySpace>>
1202createHypreSemiStructuredSolver( const std::string& solver_type,
1203 const ArrayLayout_t& layout,
1204 const bool is_preconditioner = false,
1205 int n_vars = 3 )
1206{
1208 "Must use an array layout" );
1209
1210 if ( "PCG" == solver_type )
1212 layout, is_preconditioner, n_vars );
1213 else if ( "GMRES" == solver_type )
1215 layout, is_preconditioner, n_vars );
1216 else if ( "BiCGSTAB" == solver_type )
1218 layout, is_preconditioner, n_vars );
1219 else if ( "Diagonal" == solver_type )
1221 layout, is_preconditioner, n_vars );
1222 else
1223 throw std::runtime_error(
1224 "Cabana::Grid::createHypreSemiStructuredSolver: Invalid solver "
1225 "type" );
1226}
1227
1228//---------------------------------------------------------------------------//
1229
1230} // namespace Grid
1231} // namespace Cabana
1232
1233#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:1133
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:1202
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:1162
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:1147
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:1177
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:926
void solveImpl() override
Solver implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1000
double getFinalRelativeResidualNormImpl() override
Get the relative residual norm achieved on the last solve.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1015
HYPRE_PtrToSStructSolverFcn getHypreSetupFunction() const override
Get the preconditioner setup function.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:966
void setupImpl() override
Setup implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:994
void setLogging(const int logging)
Set the amount of logging to do.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:959
HypreSemiStructBiCGSTAB(const ArrayLayout_t &layout, const bool is_preconditioner=false, int n_vars=3)
Constructor.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:933
HYPRE_SStructSolver getHypreSolver() const override
Get the preconditioner.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:965
HypreSemiStructuredSolver< Scalar, EntityType, MemorySpace > base_type
Base HYPRE semi-structured solver type.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:929
int getNumIterImpl() override
Get the number of iterations taken on the last solve.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1006
void setPrintLevelImpl(const int print_level) override
Set the output level.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:988
void setMaxIterImpl(const int max_iter) override
Set maximum iteration implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:982
HYPRE_PtrToSStructSolverFcn getHypreSolveFunction() const override
Get the preconditioner solve function.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:970
void setPreconditionerImpl(const HypreSemiStructuredSolver< Scalar, EntityType, MemorySpace > &preconditioner) override
Set a preconditioner.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1024
void setAbsoluteTol(const double tol)
Set the absolute tolerance.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:952
void setToleranceImpl(const double tol) override
Set convergence tolerance implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:976
Diagonal preconditioner.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1047
HypreSemiStructuredSolver< Scalar, EntityType, MemorySpace > base_type
Base HYPRE semi-structured solver type.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1050
void setMaxIterImpl(const int) override
Set maximum iteration implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1081
int getNumIterImpl() override
Get the number of iterations taken on the last solve.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1105
HYPRE_PtrToSStructSolverFcn getHypreSolveFunction() const override
Get the preconditioner solve function.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1069
void setPrintLevelImpl(const int) override
Set the output level.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1087
void setToleranceImpl(const double) override
Set convergence tolerance implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1075
void solveImpl() override
Solver implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1099
void setPreconditionerImpl(const HypreSemiStructuredSolver< Scalar, EntityType, MemorySpace > &) override
Set a preconditioner.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1117
HypreSemiStructDiagonal(const ArrayLayout_t &layout, const bool is_preconditioner=false, int n_vars=3)
Constructor.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1054
double getFinalRelativeResidualNormImpl() override
Get the relative residual norm achieved on the last solve.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1111
HYPRE_SStructSolver getHypreSolver() const override
Get the preconditioner.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1064
void setupImpl() override
Setup implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1093
HYPRE_PtrToSStructSolverFcn getHypreSetupFunction() const override
Get the preconditioner setup function.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:1065
GMRES solver.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:800
void setPrintLevelImpl(const int print_level) override
Set the output level.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:868
HypreSemiStructGMRES(const ArrayLayout_t &layout, int n_vars, const bool is_preconditioner=false)
Constructor.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:807
void setMaxIterImpl(const int max_iter) override
Set maximum iteration implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:862
void setToleranceImpl(const double tol) override
Set convergence tolerance implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:856
HypreSemiStructuredSolver< Scalar, EntityType, MemorySpace > base_type
Base HYPRE semi-structured solver type.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:803
int getNumIterImpl() override
Get the number of iterations taken on the last solve.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:886
HYPRE_PtrToSStructSolverFcn getHypreSolveFunction() const override
Get the preconditioner solve function.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:850
double getFinalRelativeResidualNormImpl() override
Get the relative residual norm achieved on the last solve.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:894
void setKDim(const int k_dim)
Set the max size of the Krylov space.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:832
void solveImpl() override
Solver implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:880
void setupImpl() override
Setup implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:874
HYPRE_PtrToSStructSolverFcn getHypreSetupFunction() const override
Get the preconditioner setup function.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:846
HYPRE_SStructSolver getHypreSolver() const override
Get the preconditioner.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:845
void setLogging(const int logging)
Set the amount of logging to do.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:839
void setPreconditionerImpl(const HypreSemiStructuredSolver< Scalar, EntityType, MemorySpace > &preconditioner) override
Set a preconditioner.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:903
void setAbsoluteTol(const double tol)
Set the absolute tolerance.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:825
PCG solver.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:671
HypreSemiStructPCG(const ArrayLayout_t &layout, int n_vars, const bool is_preconditioner=false)
Constructor.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:678
HYPRE_PtrToSStructSolverFcn getHypreSolveFunction() const override
Get the preconditioner solve function.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:724
void setLogging(const int logging)
Set the amount of logging to do.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:713
double getFinalRelativeResidualNormImpl() override
Get the relative residual norm achieved on the last solve.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:768
HYPRE_PtrToSStructSolverFcn getHypreSetupFunction() const override
Get the preconditioner setup function.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:720
void setPreconditionerImpl(const HypreSemiStructuredSolver< Scalar, EntityType, MemorySpace > &preconditioner) override
Set a preconditioner.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:777
void solveImpl() override
Solver implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:754
void setPrintLevelImpl(const int print_level) override
Set the output level.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:742
void setRelChange(const int rel_change)
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:706
void setMaxIterImpl(const int max_iter) override
Set maximum iteration implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:736
HYPRE_SStructSolver getHypreSolver() const override
Get the preconditioner.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:719
void setupImpl() override
Setup implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:748
void setAbsoluteTol(const double tol)
Set the absolute tolerance.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:698
HypreSemiStructuredSolver< Scalar, EntityType, MemorySpace > base_type
Base HYPRE semi-structured solver type.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:674
int getNumIterImpl() override
Get the number of iterations taken on the last solve.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:760
void setToleranceImpl(const double tol) override
Set convergence tolerance implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:730
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:477
void printLHS(const char *prefix)
Print the hypre LHS to output file.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:432
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:453
int getNumIter()
Get the number of iterations taken on the last solve.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:588
void setPreconditioner(const std::shared_ptr< HypreSemiStructuredSolver< Scalar, EntityType, MemorySpace > > &preconditioner)
Set a preconditioner.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:460
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:496
void setMaxIter(const int max_iter)
Set maximum iteration implementation.
Definition Cabana_Grid_HypreSemiStructuredSolver.hpp:450
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:646
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:591
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:447
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:441
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:631
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:650
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:423
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:648
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:324