Bembel
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 
75 int 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.
Definition: AnsatzSpace.hpp:25
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.
int main()
Routines for the evalutation of pointwise errors.
Definition: AnsatzSpace.hpp:14