Bembel
 
Loading...
Searching...
No Matches
Error.hpp
1// This file is part of Bembel, the higher order C++ boundary element library.
2//
3// Copyright (C) 2022 see <http://www.bembel.eu>
4//
5// It was written as part of a cooperation of J. Doelz, H. Harbrecht, S. Kurz,
6// M. Multerer, S. Schoeps, and F. Wolf at Technische Universitaet Darmstadt,
7// Universitaet Basel, and Universita della Svizzera italiana, Lugano. This
8// source code is subject to the GNU General Public License version 3 and
9// provided WITHOUT ANY WARRANTY, see <http://www.bembel.eu> for further
10// information.
11#ifndef EXAMPLES_ERROR_HPP_
12#define EXAMPLES_ERROR_HPP_
13
18namespace Bembel {
19
20template <typename Scalar>
21inline Eigen::Matrix<double, Eigen::Dynamic, 1> errors(
22 const Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> &pot,
23 const Eigen::MatrixXd &grid,
24 const std::function<Scalar(Eigen::Vector3d)> &fun) {
25 const int gridsz = grid.rows();
26 assert((std::max(pot.cols(), pot.rows()) == grid.rows()) &&
27 ("The size does not match!"));
28 assert((grid.cols() == 3) &&
29 "The grid must be a Matrix with a 3d point in each row!");
30 assert((std::min(pot.rows(), pot.cols())) && ("Potential must be Vector!"));
31
32 Eigen::Matrix<double, 1, Eigen::Dynamic> errors(gridsz);
33
34 for (int i = 0; i < gridsz; i++) {
35 errors(i) = std::abs(pot(i) - fun((grid.row(i).transpose()).eval()));
36 }
37 return errors;
38}
39
40inline Eigen::Matrix<double, Eigen::Dynamic, 1> errors(
41 const Eigen::MatrixXcd &pot, const Eigen::MatrixXd &grid,
42 const std::function<Eigen::Vector3cd(Eigen::Vector3d, std::complex<double>)>
43 &fun,
44 std::complex<double> kappa) {
45 const int gridsz = grid.rows();
46 assert((std::max(pot.cols(), pot.rows()) == grid.rows()) &&
47 ("The size does not match!"));
48 assert((grid.cols() == 3) &&
49 "The grid must be a Matrix with a 3d point in each row!");
50 assert((pot.cols() == 3) &&
51 ("Potential must be a Matrix with a Vector3cd in each col!"));
52 Eigen::Matrix<double, 1, Eigen::Dynamic> errors(gridsz);
53
54 for (int i = 0; i < gridsz; i++) {
55 errors(i) =
56 (pot.col(i) - fun((grid.row(i).transpose()).eval(), kappa)).norm();
57 }
58 return errors;
59}
60
61template <typename Scalar>
62inline double maxPointwiseError(
63 const Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> &pot,
64 const Eigen::MatrixXd &grid,
65 const std::function<Scalar(Eigen::Vector3d)> &fun) {
66 const int gridsz = grid.rows();
67 assert((std::max(pot.cols(), pot.rows()) == grid.rows()) &&
68 ("The size does not match!"));
69 assert((grid.cols() == 3) &&
70 "The grid must be a Matrix with a 3d point in each row!");
71 assert((std::min(pot.cols(), pot.rows()) == 1) &&
72 ("Potential must be a vector!"));
73 double error = 0;
74
75 for (int i = 0; i < gridsz; i++) {
76 double tmp = std::abs(pot(i) - fun((grid.row(i).transpose()).eval()));
77 error = tmp > error ? tmp : error;
78 }
79 return error;
80}
81
82inline double maxPointwiseError(
83 const Eigen::MatrixXcd &pot, const Eigen::MatrixXd &grid,
84 const std::function<Eigen::Vector3cd(Eigen::Vector3d)> &fun) {
85 const int gridsz = grid.rows();
86 assert(pot.cols() == grid.cols());
87 assert((std::max(pot.cols(), pot.rows()) == grid.rows()) &&
88 ("The size does not match!"));
89 assert((grid.cols() == 3) &&
90 "The grid must be a Matrix with a 3d point in each row!");
91 assert((pot.cols() == 3) &&
92 ("Must be a Matrix with a point solution in each row!"));
93 double error = 0;
94
95 for (int i = 0; i < gridsz; i++) {
96 double tmp = (pot.row(i) - fun(grid.row(i)).transpose()).norm();
97 error = tmp > error ? tmp : error;
98 }
99 return error;
100}
101
102double estimateRateOfConvergence(const Eigen::VectorXd &errors) {
103 Eigen::MatrixXd A(errors.rows(), 2);
104 A << Eigen::VectorXd::Ones(errors.rows()),
105 Eigen::VectorXd::LinSpaced(errors.rows(), 0, errors.rows() - 1);
106 Eigen::VectorXd b = errors.array().abs().log() / std::log(2);
107 Eigen::VectorXd x = A.colPivHouseholderQr().solve(b);
108 return -x(1);
109}
110
111bool checkRateOfConvergence(const Eigen::VectorXd &errors,
112 const int expected_rate, const double tol_factor,
113 double *rate_of_convergence_out = NULL) {
114 double rate_of_convergence = estimateRateOfConvergence(errors);
116 std::cout << "Estimated rate of convergence:" << rate_of_convergence
117 << std::endl;
119}
120
121} // namespace Bembel
122
123#endif // EXAMPLES_ERROR_HPP_
Routines for the evalutation of pointwise errors.
constexpr int getFunctionSpaceOutputDimension()