From 29bbaef605830d75bdc0b872cc059de3cc681ac3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= <oberhuber.tomas@gmail.com>
Date: Wed, 29 Dec 2021 14:00:35 +0100
Subject: [PATCH] Added example on linear iterative solvers with monitor and
 timer.

---
 .../Examples/Solvers/Linear/CMakeLists.txt    |   1 +
 .../IterativeLinearSolverWithTimerExample.cpp | 101 ++++++++++++++++++
 .../IterativeLinearSolverWithTimerExample.cu  |   1 +
 3 files changed, 103 insertions(+)
 create mode 100644 Documentation/Examples/Solvers/Linear/IterativeLinearSolverWithTimerExample.cpp
 create mode 120000 Documentation/Examples/Solvers/Linear/IterativeLinearSolverWithTimerExample.cu

diff --git a/Documentation/Examples/Solvers/Linear/CMakeLists.txt b/Documentation/Examples/Solvers/Linear/CMakeLists.txt
index 6cc75f08eb..a07ba232a4 100644
--- a/Documentation/Examples/Solvers/Linear/CMakeLists.txt
+++ b/Documentation/Examples/Solvers/Linear/CMakeLists.txt
@@ -1,6 +1,7 @@
 set( COMMON_EXAMPLES
    IterativeLinearSolverExample
    IterativeLinearSolverWithMonitorExample
+   IterativeLinearSolverWithTimerExample
 )
 
 if( BUILD_CUDA )
diff --git a/Documentation/Examples/Solvers/Linear/IterativeLinearSolverWithTimerExample.cpp b/Documentation/Examples/Solvers/Linear/IterativeLinearSolverWithTimerExample.cpp
new file mode 100644
index 0000000000..278ccbad0e
--- /dev/null
+++ b/Documentation/Examples/Solvers/Linear/IterativeLinearSolverWithTimerExample.cpp
@@ -0,0 +1,101 @@
+#include <iostream>
+#include <memory>
+#include <chrono>
+#include <thread>
+#include <TNL/Timer.h>
+#include <TNL/Algorithms/ParallelFor.h>
+#include <TNL/Matrices/SparseMatrix.h>
+#include <TNL/Devices/Sequential.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.5 -1    .    .    .   \
+    *   | -1    2.5 -1    .    .   |
+    *   |  .   -1    2.5 -1.   .   |
+    *   |  .    .   -1    2.5 -1   |
+    *   \  .    .    .   -1    2.5 /
+    */
+   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 );
+   solver.setOmega( 0.0005 );
+
+   /***
+    * Setup monitor of the iterative solver
+    */
+   using IterativeSolverMonitorType = TNL::Solvers::IterativeSolverMonitor< double, int >;
+   IterativeSolverMonitorType monitor;
+   TNL::Solvers::SolverMonitorThread mmonitorThread(monitor);
+   monitor.setRefreshRate(10);  // refresh rate in milliseconds
+   monitor.setVerbose(1);
+   monitor.setStage( "Jacobi stage:" );
+   TNL::Timer timer;
+   monitor.setTimer( timer );
+   timer.start();
+   solver.setSolverMonitor(monitor);
+   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::Sequential >();
+
+#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/IterativeLinearSolverWithTimerExample.cu b/Documentation/Examples/Solvers/Linear/IterativeLinearSolverWithTimerExample.cu
new file mode 120000
index 0000000000..4c497154d2
--- /dev/null
+++ b/Documentation/Examples/Solvers/Linear/IterativeLinearSolverWithTimerExample.cu
@@ -0,0 +1 @@
+IterativeLinearSolverWithTimerExample.cpp
\ No newline at end of file
-- 
GitLab