From b274befe35ab57c2dce1d6d6dccff5927e781ef7 Mon Sep 17 00:00:00 2001 From: Tomas Oberhuber <tomas.oberhuber@fjfi.cvut.cz> Date: Sun, 26 Dec 2021 22:04:34 +0100 Subject: [PATCH] Added example of iterative solver of linear systems with solver monitor. --- .../Examples/Solvers/Linear/CMakeLists.txt | 1 + ...terativeLinearSolverWithMonitorExample.cpp | 102 ++++++++++++++++++ ...IterativeLinearSolverWithMonitorExample.cu | 1 + .../Solvers/Linear/tutorial_Linear_solvers.md | 10 +- 4 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 Documentation/Examples/Solvers/Linear/IterativeLinearSolverWithMonitorExample.cpp create mode 120000 Documentation/Examples/Solvers/Linear/IterativeLinearSolverWithMonitorExample.cu diff --git a/Documentation/Examples/Solvers/Linear/CMakeLists.txt b/Documentation/Examples/Solvers/Linear/CMakeLists.txt index 5755420191..6cc75f08eb 100644 --- a/Documentation/Examples/Solvers/Linear/CMakeLists.txt +++ b/Documentation/Examples/Solvers/Linear/CMakeLists.txt @@ -1,5 +1,6 @@ set( COMMON_EXAMPLES IterativeLinearSolverExample + IterativeLinearSolverWithMonitorExample ) if( BUILD_CUDA ) diff --git a/Documentation/Examples/Solvers/Linear/IterativeLinearSolverWithMonitorExample.cpp b/Documentation/Examples/Solvers/Linear/IterativeLinearSolverWithMonitorExample.cpp new file mode 100644 index 0000000000..ac3a8f83e4 --- /dev/null +++ b/Documentation/Examples/Solvers/Linear/IterativeLinearSolverWithMonitorExample.cpp @@ -0,0 +1,102 @@ +#include <iostream> +#include <memory> +#include <chrono> +#include <thread> +#include <TNL/Algorithms/ParallelFor.h> +#include <TNL/Matrices/SparseMatrix.h> +#include <TNL/Devices/Host.h> +#include <TNL/Devices/Cuda.h> +#include <TNL/Solvers/Linear/Jacobi.h> + +template< typename Device > +void iterativeLinearSolverExample() +{ + /*** + * Set the following matrix (dots represent zero matrix elements): + * + * / 2 -1 . . . \ + * | -1 2 -1 . . | + * | . -1 2 -1. . | + * | . . -1 2 -1 | + * \ . . . -1 2 / + */ + using MatrixType = TNL::Matrices::SparseMatrix< double, Device >; + using Vector = TNL::Containers::Vector< double, Device >; + const int size( 5 ); + auto matrix_ptr = std::make_shared< MatrixType >(); + matrix_ptr->setDimensions( size, size ); + matrix_ptr->setRowCapacities( Vector( { 2, 3, 3, 3, 2 } ) ); + + auto f = [=] __cuda_callable__ ( typename MatrixType::RowView& row ) mutable { + const int rowIdx = row.getRowIndex(); + if( rowIdx == 0 ) + { + row.setElement( 0, rowIdx, 2.5 ); // diagonal element + row.setElement( 1, rowIdx+1, -1 ); // element above the diagonal + } + else if( rowIdx == size - 1 ) + { + row.setElement( 0, rowIdx-1, -1.0 ); // element below the diagonal + row.setElement( 1, rowIdx, 2.5 ); // diagonal element + } + else + { + row.setElement( 0, rowIdx-1, -1.0 ); // element below the diagonal + row.setElement( 1, rowIdx, 2.5 ); // diagonal element + row.setElement( 2, rowIdx+1, -1.0 ); // element above the diagonal + } + }; + + /*** + * Set the matrix elements. + */ + matrix_ptr->forAllRows( f ); + std::cout << *matrix_ptr << std::endl; + + /*** + * Set the right-hand side vector + */ + Vector x( size, 1.0 ); + Vector b( size ); + matrix_ptr->vectorProduct( x, b ); + x = 0.0; + std::cout << "Vector b = " << b << std::endl; + + /*** + * Setup solver of the linear system + */ + using LinearSolver = TNL::Solvers::Linear::Jacobi< MatrixType >; + LinearSolver solver; + solver.setMatrix( matrix_ptr ); + + + /*** + * Setup monitor of the iterative solver + */ + using IterativeSolverMonitorType = TNL::Solvers::IterativeSolverMonitor< double, int >; + IterativeSolverMonitorType monitor; + TNL::Solvers::SolverMonitorThread t(monitor); + monitor.setRefreshRate(100); // refresh rate = timeout in milliseconds + monitor.setVerbose(1); + monitor.setStage( "Jacobi stage:" ); + TNL::Timer timer; + monitor.setTimer( timer ); + solver.setSolverMonitor(monitor); + solver.setOmega( 0.001 ); + //std::this_thread::sleep_for(std::chrono::milliseconds(3000)); // wait for 3 seconds to let the monitor doing something + timer.start(); + solver.solve( b, x ); + monitor.stopMainLoop(); + std::cout << "Vector x = " << x << std::endl; +} + +int main( int argc, char* argv[] ) +{ + std::cout << "Solving linear system on host: " << std::endl; + iterativeLinearSolverExample< TNL::Devices::Host >(); + +#ifdef HAVE_CUDA + std::cout << "Solving linear system on CUDA device: " << std::endl; + iterativeLinearSolverExample< TNL::Devices::Cuda >(); +#endif +} diff --git a/Documentation/Examples/Solvers/Linear/IterativeLinearSolverWithMonitorExample.cu b/Documentation/Examples/Solvers/Linear/IterativeLinearSolverWithMonitorExample.cu new file mode 120000 index 0000000000..c0474305b0 --- /dev/null +++ b/Documentation/Examples/Solvers/Linear/IterativeLinearSolverWithMonitorExample.cu @@ -0,0 +1 @@ +IterativeLinearSolverWithMonitorExample.cpp \ No newline at end of file diff --git a/Documentation/Tutorials/Solvers/Linear/tutorial_Linear_solvers.md b/Documentation/Tutorials/Solvers/Linear/tutorial_Linear_solvers.md index 2df2f73191..24516565c2 100644 --- a/Documentation/Tutorials/Solvers/Linear/tutorial_Linear_solvers.md +++ b/Documentation/Tutorials/Solvers/Linear/tutorial_Linear_solvers.md @@ -35,4 +35,12 @@ All iterative solvers for linear systems can be found in the namespace \ref TNL: The result looks as follows: -\include IterativeLinearSolverExample.out \ No newline at end of file +\include IterativeLinearSolverExample.out + + + +\includelineno Solvers/Linear/IterativeLinearSolverWithMonitorExample.cpp + +The result looks as follows: + +\include IterativeLinearSolverWithMonitorExample.out \ No newline at end of file -- GitLab