NiHu  2.0
helmholtz_3d_transparent_standalone.cpp
1 #include <boost/math/constants/constants.hpp>
2 
5 #include "library/helmholtz_3d.hpp"
7 
8 #include <iostream>
9 
10 typedef Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> dMatrix;
11 typedef Eigen::Matrix<unsigned, Eigen::Dynamic, Eigen::Dynamic> uMatrix;
12 typedef Eigen::Matrix<std::complex<double>, Eigen::Dynamic, Eigen::Dynamic> cMatrix;
13 
14 template <class TestSpace, class TrialSpace>
15 static double tester(TestSpace const &test_space, TrialSpace const &trial_space)
16 {
17  using namespace boost::math::double_constants;
18 
19  double wn = 1.;
20 
21  // instantiate integral operators
25 
26  size_t N = test_space.get_num_dofs();
27 
28  // excitation and response
29  cMatrix q0(N, 1), p0(N,1);
30  p0.setZero();
31  q0.setZero();
32 
33  dMatrix x0(3, 2);
34  x0 <<
35  .2, .3,
36  .3, .2,
37  .1, .2;
38  dMatrix A(1, 3);
39  A << 1.0, -1.0, -2.0;
40 
41  auto const &mesh = trial_space.get_mesh();
42  for (size_t k = 0; k < N; ++k)
43  {
44  auto const &elem = mesh.template get_elem<NiHu::tria_1_elem>(k);
45  auto y = elem.get_center();
46  auto ny = elem.get_normal().normalized();
47  for (int s = 0; s < x0.cols(); ++s)
48  {
49  auto rvec = y - x0.col(s);
50  double r = rvec.norm();
51  std::complex<double> ikr(0., wn*r);
52  double rdn = rvec.dot(ny) / r;
53  p0(k) += A(s) * std::exp(-ikr)/r/(4. * pi);
54  q0(k) += A(s) * -(std::exp(-ikr)/r/r) * rdn /(4. * pi) * (1. + ikr);
55  }
56  }
57 
58  // system matrices
59  cMatrix L(N, N), M(N, N), I(N,N);
60  L.setZero(); M.setZero(); I.setZero();
61 
62  I << test_space * I_op[trial_space];
63  L << test_space * L_op[trial_space];
64  M << test_space * M_op[trial_space];
65 
66  std::cout << I.block(0, 0, 5, 5) << std::endl << std::endl;
67  std::cout << L.block(0, 0, 5, 5) << std::endl << std::endl;
68  std::cout << M.block(0, 0, 5, 5) << std::endl << std::endl;
69 
70  cMatrix p = (M - .5 * I).colPivHouseholderQr().solve(L * q0);
71 
72  return (p-p0).norm() / p0.norm();
73 }
74 
75 int main(int argc, char *argv[])
76 {
77  if (argc < 2)
78  {
79  std::cerr << "Usage: " << argv[0] << " OFFname" << std::endl;
80  return 1;
81  }
82 
83  // read mesh
84  auto mesh = NiHu::read_off_mesh(argv[1], NiHu::tria_1_tag());
85  auto const &trial_space = NiHu::constant_view(mesh);
86 
87  std::cout << "Collocation" << std::endl;
88  double coll_error = tester(NiHu::dirac(trial_space), trial_space);
89  std::cout << coll_error << std::endl;
90 
91  std::cout << "Galerkin" << std::endl;
92  double gal_error = tester(trial_space, trial_space);
93  std::cout << gal_error << std::endl;
94 
95  return 0;
96 }
97 
NiHu::create_integral_operator
integral_operator< Kernel > create_integral_operator(Kernel &&kernel)
factory function of an integral operator
Definition: integral_operator.hpp:421
read_off_mesh.hpp
export NiHu mesh from OFF format
NiHu::read_off_mesh
mesh< tmp::vector< typename tag2type< Tags >::type... > > read_off_mesh(std::string const &fname, Tags...tags)
Read mesh from OFF format.
Definition: read_off_mesh.hpp:153
NiHu::type2tag
Metafunction assigning a tag to a type.
Definition: type2tag.hpp:17
NiHu::constant_view
const function_space_view< Mesh, field_option::constant, Dimension > & constant_view(mesh_base< Mesh > const &msh, Dimension dim=Dimension())
factory function to transform a mesh into a constant function space
Definition: function_space.hpp:304
weighted_residual.hpp
declaration of class NiHu::weighted_residual
lib_element.hpp
NiHu::mex::real_matrix
Definition: mex_matrix_separate.hpp:133
NiHu::normal_derivative_kernel
Normal derivative of a distance dependent kernel.
Definition: normal_derivative_kernel.hpp:26
NiHu::identity_integral_operator
The identity integral operator .
Definition: integral_operator.hpp:310