Bembel
 
Loading...
Searching...
No Matches
LaplaceSingleLayerFull.cpp
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#include <Bembel/AnsatzSpace>
12#include <Bembel/Geometry>
13#include <Bembel/H2Matrix>
14#include <Bembel/IO>
15#include <Bembel/Laplace>
16#include <Bembel/LinearForm>
17#include <Eigen/Dense>
18#include <iostream>
19
20#include "examples/Data.hpp"
21#include "examples/Error.hpp"
22#include "examples/Grids.hpp"
23
75int main() {
76 using namespace Bembel;
77 using namespace Eigen;
79
80 int polynomial_degree_max = 3;
81 int refinement_level_max = 3;
82
84 Geometry geometry("sphere.dat");
85
87 MatrixXd gridpoints = Util::makeTensorProductGrid(
88 VectorXd::LinSpaced(10, -.25, .25), VectorXd::LinSpaced(10, -.25, .25),
89 VectorXd::LinSpaced(10, -.25, .25));
90
92 std::function<double(Vector3d)> fun = [](Vector3d in) {
93 return Data::HarmonicFunction(in);
94 };
95
96 std::cout << "\n" << std::string(60, '=') << "\n";
97 // Iterate over polynomial degree.
98 for (int polynomial_degree = 0; polynomial_degree < polynomial_degree_max + 1;
99 ++polynomial_degree) {
100 VectorXd error(refinement_level_max + 1);
101 // Iterate over refinement levels
102 for (int refinement_level = 0; refinement_level < refinement_level_max + 1;
103 ++refinement_level) {
104 sw.tic();
105
106 std::cout << "Degree " << polynomial_degree << " Level "
107 << refinement_level << "\t\t";
108
112 geometry, refinement_level, polynomial_degree);
113
116 disc_lf(ansatz_space);
117 disc_lf.get_linear_form().set_function(fun);
118 disc_lf.compute();
119
123 ansatz_space);
124 disc_op.compute();
125
127 LLT<MatrixXd> llt;
128 llt.compute(disc_op.get_discrete_operator());
129 auto rho = llt.solve(disc_lf.get_discrete_linear_form());
130
135 disc_pot(ansatz_space);
136 disc_pot.set_cauchy_data(rho);
137 auto pot = disc_pot.evaluate(gridpoints);
138
140 VectorXd pot_ref(gridpoints.rows());
141 for (int i = 0; i < gridpoints.rows(); ++i)
142 pot_ref(i) = fun(gridpoints.row(i));
143 error(refinement_level) = (pot - pot_ref).cwiseAbs().maxCoeff();
144 std::cout << " time " << std::setprecision(4) << sw.toc() << "s\t\t";
145 std::cout << error(refinement_level) << std::endl;
146 }
147
148 // estimate rate of convergence and check whether it is at least 90% of the
149 // expected value
150 assert(
151 checkRateOfConvergence(error.tail(2), 2 * polynomial_degree + 3, 0.9));
152
153 std::cout << std::endl;
154 }
155 std::cout << std::string(60, '=') << std::endl;
156
157 return 0;
158}
The AnsatzSpace is the class that handles the assembly of the discrete basis.
This class, given a LinearForm with defined traits, takes care of the assembly of the right hand side...
this class wraps a GeometryVector and provides some basic functionality, like reading Geometry files
Definition Geometry.hpp:20
A simple class for benchmarking.
Definition Stopwatch.hpp:27
This class implements the specification of the integration for the single layer operator for Laplace.
Routines for the evalutation of pointwise errors.