Feellgood
block_precond.h
1 #ifndef BLOCK_PRECOND_H
2 #define BLOCK_PRECOND_H
3 
4 #include <stdexcept>
5 #include <vector>
6 
7 #include <eigen3/Eigen/Dense>
8 
9 #include "sparseMat.h"
10 
11 namespace algebra
12 {
22 template <int BS>
24  {
25 public:
28  BlockDiagPrecond(const SparseMatrix &A, const int nbBlocks, const std::vector<int> &ld)
29  : inv(nbBlocks)
30  {
31  std::vector<char> dir(BS * nbBlocks, 0);
32  for (const int i : ld)
33  { dir[i] = 1; }
34  for (int n = 0; n < nbBlocks; n++)
35  {
36  Eigen::Matrix<double, BS, BS> a;
37  for (int r = 0; r < BS; r++)
38  for (int c = 0; c < BS; c++)
39  {
40  const int I = BS * n + r, J = BS * n + c;
41  a(r, c) = (dir[I] || dir[J]) ? (r == c ? 1.0 : 0.0) : A(I, J);
42  }
43  if (a.determinant() == 0.0)
44  { throw std::runtime_error("BlockDiagPrecond: singular diagonal block"); }
45  inv[n] = a.inverse();
46  }
47  }
48 
50  void apply(const std::vector<double> &x, std::vector<double> &y) const
51  {
52  for (size_t n = 0; n < inv.size(); n++)
53  {
54  Eigen::Map<const Eigen::Matrix<double, BS, 1>> xb(&x[BS * n]);
55  Eigen::Map<Eigen::Matrix<double, BS, 1>> yb(&y[BS * n]);
56  yb = inv[n] * xb;
57  }
58  }
59 
60 private:
62  std::vector<Eigen::Matrix<double, BS, BS>> inv;
63  };
64 
65 } // namespace algebra
66 #endif
Definition: block_precond.h:24
std::vector< Eigen::Matrix< double, BS, BS > > inv
Definition: block_precond.h:62
void apply(const std::vector< double > &x, std::vector< double > &y) const
Definition: block_precond.h:50
BlockDiagPrecond(const SparseMatrix &A, const int nbBlocks, const std::vector< int > &ld)
Definition: block_precond.h:28
Square sparse matrix.
Definition: sparseMat.h:46
constexpr double A
Definition: tetra.h:52
constexpr double a[N][NPI]
Definition: tetra.h:68
Sparse matrices.