Skip to content
Snippets Groups Projects
Commit 2785e868 authored by Stéphane Del Pino's avatar Stéphane Del Pino
Browse files

Add BiCGStab and make few clean-up

parent 748f9b14
No related branches found
No related tags found
1 merge request!26Feature/linear systems
#ifndef BICG_STAB_HPP
#define BICG_STAB_HPP
#include <iostream>
class BiCGStab
{
public:
template <typename VectorType, typename MatrixType, typename PreconditionerType>
BiCGStab(const VectorType& b,
const MatrixType& A,
[[maybe_unused]] const PreconditionerType& P,
VectorType& x,
const size_t max_iter,
const double epsilon = 1e-6)
{
std::cout << "- bi-conjugate gradient stabilized\n";
std::cout << " epsilon = " << epsilon << '\n';
std::cout << " maximum number of iterations: " << max_iter << '\n';
VectorType r_k_1{b.size()};
r_k_1 = b - A * x;
double residu = std::sqrt((r_k_1, r_k_1)); // Norm(r_k_1);
if (residu != 0) {
double resid0 = residu;
VectorType rTilda_0 = copy(r_k_1);
VectorType p_k = copy(r_k_1);
VectorType s_k{x.size()};
VectorType Ap_k{x.size()};
VectorType As_k{x.size()};
VectorType r_k{x.size()};
std::cout << " initial residu: " << resid0 << '\n';
for (size_t i = 1; i <= max_iter; ++i) {
std::cout << " - iteration: " << std::setw(6) << i << "\tresidu: " << residu / resid0
<< "\tabsolute: " << residu << '\n';
Ap_k = A * p_k;
const double alpha_k = (r_k_1, rTilda_0) / (Ap_k, rTilda_0);
s_k = r_k_1 - alpha_k * Ap_k;
As_k = A * s_k;
const double w_k = (As_k, s_k) / (As_k, As_k);
x += alpha_k * p_k + w_k * s_k;
r_k = s_k - w_k * As_k;
const double beta_k = (r_k, rTilda_0) / (r_k_1, rTilda_0) * (alpha_k / w_k);
p_k -= w_k * Ap_k;
p_k *= beta_k;
p_k += r_k;
if ((residu = std::sqrt((r_k, r_k))) / resid0 < epsilon) {
break;
}
r_k_1 = r_k;
}
if (residu / resid0 > epsilon) {
std::cout << " bi_conjugate gradient stabilized: *NOT CONVERGED*\n";
std::cout << " - epsilon: " << epsilon << '\n';
std::cout << " - relative residu : " << residu / resid0 << '\n';
std::cout << " - absolute residu : " << residu << '\n';
}
}
std::cout << "- bi-conjugate gradient stabilized: done\n";
}
};
#endif // BICG_STAB_HPP
...@@ -38,7 +38,7 @@ struct PCG ...@@ -38,7 +38,7 @@ struct PCG
cg -= h; cg -= h;
g = copy(cg); // C.computes(cg, g); g = copy(cg); // TODO: precond: g = g/C
gcg = (g, cg); gcg = (g, cg);
...@@ -55,8 +55,7 @@ struct PCG ...@@ -55,8 +55,7 @@ struct PCG
double ro = gcg / hAh; double ro = gcg / hAh;
cg -= ro * b; cg -= ro * b;
// VectorType b2 = b; // TODO: precond: b <- b/C
// C.computes(b2, b);
x += ro * h; x += ro * h;
g -= ro * b; g -= ro * b;
......
...@@ -103,7 +103,7 @@ class Vector ...@@ -103,7 +103,7 @@ class Vector
PUGS_INLINE PUGS_INLINE
Vector Vector
operator+(const Vector& y) operator+(const Vector& y) const
{ {
Assert(this->size() == y.size()); Assert(this->size() == y.size());
Vector sum{y.size()}; Vector sum{y.size()};
...@@ -116,7 +116,7 @@ class Vector ...@@ -116,7 +116,7 @@ class Vector
PUGS_INLINE PUGS_INLINE
Vector Vector
operator-(const Vector& y) operator-(const Vector& y) const
{ {
Assert(this->size() == y.size()); Assert(this->size() == y.size());
Vector sum{y.size()}; Vector sum{y.size()};
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <SynchronizerManager.hpp> #include <SynchronizerManager.hpp>
#include <BiCGStab.hpp>
#include <CRSMatrix.hpp> #include <CRSMatrix.hpp>
#include <PCG.hpp> #include <PCG.hpp>
...@@ -41,6 +42,7 @@ main(int argc, char* argv[]) ...@@ -41,6 +42,7 @@ main(int argc, char* argv[])
Kokkos::initialize({4, -1, -1, true}); Kokkos::initialize({4, -1, -1, true});
{ {
{ // PCG simple test
size_t matrix_size = 10; size_t matrix_size = 10;
FlexibleMatrix F(matrix_size); FlexibleMatrix F(matrix_size);
...@@ -51,31 +53,59 @@ main(int argc, char* argv[]) ...@@ -51,31 +53,59 @@ main(int argc, char* argv[])
F(i + 1, i) = -1; F(i + 1, i) = -1;
} }
} }
std::cout << F << '\n';
CRSMatrix A{F}; CRSMatrix A{F};
std::cout << A << '\n';
Vector<double> x{10}; Vector<double> x{10};
for (size_t i = 0; i < x.size(); ++i) { for (size_t i = 0; i < x.size(); ++i) {
x[i] = 2 * i + 1; x[i] = 2 * i + 1;
} }
std::cout << "x=\n" << x << '\n';
Vector<double> Ax = A * x; Vector<double> Ax = A * x;
std::cout << "Ax=\n" << Ax << '\n';
Vector<double> u{x.size()}; Vector<double> u{x.size()};
u = 0; u = 0;
PCG{Ax, A, A, u, static_cast<size_t>(-1), 1e-12}; PCG{Ax, A, A, u, 100, 1e-12};
std::cout << "u=\n" << u << '\n';
std::cout << "== PCG report ==\n";
std::cout << "L2 Error = " << std::sqrt((x - u, x - u)) << '\n';
std::cout << "L2 Norm = " << std::sqrt((x, x)) << '\n';
std::cout << "L2 RelEr = " << std::sqrt((x - u, x - u)) / std::sqrt((x, x)) << '\n';
std::cout << "================\n";
}
{ // BiCGStab simple test
size_t matrix_size = 10;
FlexibleMatrix F(matrix_size);
for (size_t i = 0; i < matrix_size; ++i) {
F(i, i) = 4;
if (i + 1 < matrix_size) {
F(i, i + 1) = -1;
F(i + 1, i) = -0.3;
}
}
CRSMatrix A{F};
Vector<double> x{10};
for (size_t i = 0; i < x.size(); ++i) {
x[i] = 2 * i + 1;
}
Vector<double> Ax = A * x;
Vector<double> u{x.size()};
u = 0;
BiCGStab{Ax, A, A, u, 100, 1e-12};
std::cout << "== BiCGStab report ==\n";
std::cout << "L2 Error = " << std::sqrt((x - u, x - u)) << '\n'; std::cout << "L2 Error = " << std::sqrt((x - u, x - u)) << '\n';
std::cout << "L2 Norm = " << std::sqrt((x, x)) << '\n'; std::cout << "L2 Norm = " << std::sqrt((x, x)) << '\n';
std::cout << "L2 RelEr = " << std::sqrt((x - u, x - u)) / std::sqrt((x, x)) << '\n'; std::cout << "L2 RelEr = " << std::sqrt((x - u, x - u)) / std::sqrt((x, x)) << '\n';
std::cout << "=====================\n";
}
} }
Kokkos::finalize(); Kokkos::finalize();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment