OpenBEM
Open-source framework for electromagnetic simulation with the boundary element method.
Loading...
Searching...
No Matches
eigen_base.hpp
Go to the documentation of this file.
1// OpenBEM - Copyright (C) 2026 Shashwat Sharma
2
3// This file is part of OpenBEM.
4
5// OpenBEM is free software: you can redistribute it and/or modify it under the terms of the
6// GNU General Public License as published by the Free Software Foundation, either version 3
7// of the License, or (at your option) any later version.
8
9// You should have received a copy of the GNU General Public License along with OpenBEM.
10// If not, see <https://www.gnu.org/licenses/>.
11
12
18#ifndef EIGEN_MATRIX_BASE_HPP
19#define EIGEN_MATRIX_BASE_HPP
20
21#include <memory>
22
23#include <external/Eigen/Dense>
24#include <external/Eigen/IterativeLinearSolvers>
25#include <external/EigenUnsupported/Eigen/IterativeSolvers>
26
27#include "types.hpp"
28#include "matrix/base.hpp"
29
30
31namespace bem
32{
33
45template <typename T, typename MatrixType>
47{
48public:
49
55 EigenMatrixBase(Index rows, Index cols): matrix_(std::make_shared<MatrixType> ())
56 {
58 set_zero();
59 return;
60 };
61
62
67
68
76 virtual void set_block(
77 const MatrixBase<T>& x,
80 const T& a = T(1)
81 ) = 0;
82
83
92 virtual void add_block(
93 const MatrixBase<T>& x,
96 const T& a = T(1)
97 ) = 0;
98
99
108 virtual void get_block(
114 ) const = 0;
115
116
120 MatrixType& raw_matrix()
121 {
122 return *matrix_;
123 };
124
125
129 const MatrixType& raw_matrix() const
130 {
131 return *matrix_;
132 };
133
134
139 void set_raw_matrix(const MatrixType& matrix)
140 {
141 matrix_ = std::make_shared<MatrixType> (matrix);
142 return;
143 };
144
145
154 void bind_raw_matrix(std::shared_ptr<MatrixType> matrix)
155 {
156 matrix_ = std::move(matrix);
157 return;
158 };
159
160
165 Index num_rows() const override
166 {
167 return matrix_->rows();
168 };
169
170
175 Index num_cols() const override
176 {
177 return matrix_->cols();
178 };
179
180
185 Index size() const override
186 {
187 return matrix_->size();
188 };
189
190
196 void resize(Index rows, Index cols) override
197 {
198 matrix_->resize(rows, cols);
199 set_zero();
200 return;
201 };
202
203
207 void clear() override
208 {
209 resize(0, 0);
210 return;
211 };
212
213
217 void set_zero() override
218 {
219 matrix_->setZero();
220 return;
221 };
222
223
227 void set_identity() override
228 {
229 matrix_->setIdentity();
230 return;
231 };
232
233
234
241 {
243 (*matrix_) = xd.raw_matrix().transpose();
244 return;
245 };
246
247
253 {
255 xd.raw_matrix() = matrix_->diagonal().asDiagonal();
256 return;
257 };
258
259
266 void add_ax(const MatrixBase<T>& x, const T& a = T(1)) override
267 {
269 raw_matrix() += a * xd.raw_matrix();
270 return;
271 };
272
273
282 void set_axpby(const MatrixBase<T>& x, const MatrixBase<T>& y, const T& a = T(1), const T& b = T(1))
283 {
286 raw_matrix() = a * xd.raw_matrix() + b * yd.raw_matrix();
287 return;
288 };
289
290
298 void set_mat_mul(const MatrixBase<T>& x, const MatrixBase<T>& y, const T& a = T(1))
299 {
302 raw_matrix() = xd.raw_matrix() * yd.raw_matrix() * a;
303 return;
304 };
305
306
314 void add_mat_mul(const MatrixBase<T>& x, const MatrixBase<T>& y, const T& a = T(1))
315 {
318 raw_matrix() += xd.raw_matrix() * yd.raw_matrix() * a;
319 return;
320 };
321
322
323
332 void mat_solve_iterative(MatrixBase<T>& x, const MatrixBase<T>& b, const Float tol = 1e-3)
333 {
334 mat_solve_gmres(x, b, tol);
335 // mat_solve_bicgstab(x, b, tol);
336 return;
337 };
338
339
350 MatrixBase<T>& x, const MatrixBase<T>& b, const Float tol = 1e-3, const Index restart = 100
351 )
352 {
353 Eigen::GMRES<MatrixType, Eigen::IdentityPreconditioner> solver;
354 // Eigen::GMRES<MatrixType, Eigen::DiagonalPreconditioner<T>> solver;
355
356 solver.setTolerance(tol);
357 solver.setMaxIterations(1000);
358 solver.set_restart(restart);
359
360 solver.compute(raw_matrix());
361 if (solver.info() != Eigen::Success)
362 throw std::runtime_error("Matrix solver initialization failed.");
363
366
367 xd.raw_matrix() = solver.solve(bd.raw_matrix());
368
369 std::cout << "GMRES iterations: " << solver.iterations() << " | tolerance: " << solver.tolerance() << " | residual: " << solver.error() << std::endl;
370
371 // xd.resize(num_cols(), bd.num_cols());
372 // for (Index ii = 0; ii < bd.num_cols(); ++ii)
373 // xd.raw_matrix().col(ii) = solver.solve(bd.raw_matrix().col(ii));
374
375 if (solver.info() != Eigen::Success)
376 std::cout << "Warning: GMRES solve failed." << std::endl;
377
378 return;
379 };
380
381
390 void mat_solve_bicgstab(MatrixBase<T>& x, const MatrixBase<T>& b, const Float tol = 1e-3)
391 {
392 Eigen::BiCGSTAB<MatrixType, Eigen::IdentityPreconditioner> solver;
393 // Eigen::BiCGSTAB<MatrixType, Eigen::DiagonalPreconditioner<T>> solver;
394
395 solver.setTolerance(tol);
396 solver.setMaxIterations(1000);
397
398 solver.compute(raw_matrix());
399 if (solver.info() != Eigen::Success)
400 throw std::runtime_error("Matrix solver initialization failed.");
401
404
405 xd.raw_matrix() = solver.solve(bd.raw_matrix());
406
407 std::cout << "BiCGStab iterations: " << solver.iterations() << " | tolerance: " << solver.tolerance() << " | residual: " << solver.error() << std::endl;
408
409 // xd.resize(num_cols(), bd.num_cols());
410 // for (Index ii = 0; ii < bd.num_cols(); ++ii)
411 // xd.raw_matrix().col(ii) = solver.solve(bd.raw_matrix().col(ii));
412
413 if (solver.info() != Eigen::Success)
414 std::cout << "Warning: BiCGStab solve failed." << std::endl;
415
416 return;
417 };
418
419
424 Float cond() const
425 {
426 // Eigen::JacobiSVD<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>> svd (
427 // (Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>) raw_matrix()
428 // );
429 Eigen::BDCSVD<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>> svd (
430 (Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>) raw_matrix()
431 );
432 EigColVec<Float> s = svd.singularValues();
433 return s(0) / s(s.size() - 1);
434 };
435
436
440 void print(const std::string name = "matrix") const override
441 {
442 std::cout << "\n--- " << name << " (" << num_rows() << " x " << num_cols() << ") ---" << std::endl;
443 std::cout << raw_matrix() << std::endl;
444 std::cout << "---" << std::endl;
445 return;
446 };
447
448
449protected:
450
451 std::shared_ptr<MatrixType> matrix_ = nullptr;
452
453};
454
459}
460
461#endif
Base class for Eigen-based matrices.
void clear() override
Clears all data in the matrix and sets its size to 0.
Index num_cols() const override
Returns the total number of rows in the matrix.
void set_identity() override
Sets the matrix to identity (ones along the diagonal).
virtual void add_block(const MatrixBase< T > &x, Index row_start, Index col_start, const T &a=T(1))=0
Adds a block of values to this matrix from the values of a given matrix, starting at a given position...
Index num_rows() const override
Returns the total number of rows in the matrix.
const MatrixType & raw_matrix() const
Returns a read-only reference to the underlying raw matrix.
void mat_solve_bicgstab(MatrixBase< T > &x, const MatrixBase< T > &b, const Float tol=1e-3)
Solves for matrix with the BiCGSTAB iterative solver, where is this matrix, and is a given right-...
void set_transpose(const MatrixBase< T > &x)
Computes where is this matrix, is a given matrix, and is its transpose.
Index size() const override
Returns the size (rows * cols) of the matrix.
virtual void get_block(MatrixBase< T > &x, Index row_start, Index col_start, Index b_rows, Index b_cols) const =0
Retrieves a block of values from this matrix.
void resize(Index rows, Index cols) override
Resizes the matrix to a new number of rows and columns.
void get_diagonal(MatrixBase< T > &x) const
Retrieves matrix values on the diagonal, zeroing out all other entries.
void bind_raw_matrix(std::shared_ptr< MatrixType > matrix)
Binds the underlying raw matrix to the data pointed at by a given matrix pointer.
void mat_solve_gmres(MatrixBase< T > &x, const MatrixBase< T > &b, const Float tol=1e-3, const Index restart=100)
Solves for matrix with the GMRES iterative solver, where is this matrix, and is a given right-han...
virtual void set_block(const MatrixBase< T > &x, Index row_start, Index col_start, const T &a=T(1))=0
Sets a block of values in this matrix to the values of a given matrix, starting at a given position.
void print(const std::string name="matrix") const override
Prints the matrix to the terminal in a formatted manner.
void set_axpby(const MatrixBase< T > &x, const MatrixBase< T > &y, const T &a=T(1), const T &b=T(1))
Computes where is this matrix, and are scalars, and and are matrices.
void mat_solve_iterative(MatrixBase< T > &x, const MatrixBase< T > &b, const Float tol=1e-3)
Solves for matrix with an iterative solver, where is this matrix, and is a given right-hand side ...
Float cond() const
Computes the condition number (ratio of largest to smallest singular value) of the matrix.
void set_mat_mul(const MatrixBase< T > &x, const MatrixBase< T > &y, const T &a=T(1))
Computes where is this matrix, is a scalar, and and are matrices.
EigenMatrixBase()
Constructs an empty zero-size EigenMatrixBase object.
void set_zero() override
Sets all matrix entries to zero.
void set_raw_matrix(const MatrixType &matrix)
Sets the underlying raw matrix by copying over data from a given matrix.
void add_mat_mul(const MatrixBase< T > &x, const MatrixBase< T > &y, const T &a=T(1))
Computes where is this matrix, is a scalar, and and are matrices.
void add_ax(const MatrixBase< T > &x, const T &a=T(1)) override
Computes where is this matrix, is a scalar, and is a matrix.
MatrixType & raw_matrix()
Returns a writable reference to the underlying raw matrix - use with caution.
EigenMatrixBase(Index rows, Index cols)
Constructs an EigenMatrixBase object with a specified number of rows and columns.
Base class for for matrix algebra containers.
Definition base.hpp:46
double Float
Floating point number.
Definition types.hpp:47
Eigen::Matrix< T, N, 1 > EigColVecN
Fixed-size column vector of size N containing type T.
Definition types.hpp:86
std::size_t Index
Unsigned integer type for indices and container sizes.
Definition types.hpp:54
Primary namespace for the OpenBEM library.
Definition constants.hpp:31