NiHu  2.0
nearly_singular_collocational_telles.hpp
1 #ifndef NIHU_NEARLY_SINGULAR_COLLOCATIONAL_TELLES_HPP_INCLUDED
2 #define NIHU_NEARLY_SINGULAR_COLLOCATIONAL_TELLES_HPP_INCLUDED
3 
4 #include "line_quad_store.hpp"
5 #include "location_normal.hpp"
6 #include "weighted_input.hpp"
7 #include "telles_1987.hpp"
8 #include "../core/element.hpp"
9 #include "../core/field.hpp"
10 #include "../core/inverse_mapping.hpp"
11 #include "../core/kernel.hpp"
12 #include "../core/nearly_singular_planar_constant_collocation_shortcut.hpp"
13 #include "../core/shapeset.hpp"
14 #include "../util/block_product.hpp"
15 
16 namespace NiHu
17 {
18 
19 namespace internal
20 {
21 
27 template <class Domain>
28 struct telles_transformer
29 {
30  typedef Domain domain_t;
31  typedef gaussian_quadrature<domain_t> quad_t;
32 
33  typedef typename domain_t::xi_t xi_t;
34  typedef typename domain_t::scalar_t scalar_t;
35 
36  telles_transformer(unsigned Order)
37  : m_quad_orig(Order)
38  {
39 
40  }
41 
42  quad_t transform(xi_t const& xi0, scalar_t const& zeta0)
43  {
44  return telles_transform(m_quad_orig, xi0, zeta0);
45  }
46 
47 private:
48  quad_t const m_quad_orig;
49 };
50 
59 template <>
60 struct telles_transformer<tria_domain>
61 {
62  typedef tria_domain domain_t;
63  typedef gaussian_quadrature<domain_t> tria_quad_t;
64  typedef gaussian_quadrature<line_domain> line_quad_t;
65 
66  typedef typename domain_t::xi_t xi_t;
67  typedef typename domain_t::scalar_t scalar_t;
68 
69  telles_transformer(unsigned Order)
70  : m_quad_line(Order)
71  {
72  }
73 
74  tria_quad_t transform(xi_t const& xi0, scalar_t const& zeta0)
75  {
76  tria_quad_t quad_tria;
77  size_t const n = m_quad_line.size();
78  quad_tria.resize(n*n);
79 
80  typename line_domain::xi_t xi1_bar(2.0*xi0(0) - 1.0);
81  // The jacobian of the re-transformation in xi_1
82  scalar_t jac1 = 2.0;
83 
84  // Transform the original line quadrature
85  line_quad_t xi1_quad = telles_transform(m_quad_line, xi1_bar, zeta0 * jac1);
86 
87  for (size_t i = 0; i < xi1_quad.size(); ++i) {
88  // Actual coordinate in xi1
89  scalar_t xi1 = (1.0 + xi1_quad[i].get_xi()(0)) / 2.0;
90  // Re-transform the singular point in xi_2 from [0, 1-xi1] to [-1, 1]
91  typename line_domain::xi_t xi2_bar(2.0*xi0(1) / (1.0 - xi1) - 1.0);
92  // The jacobian of the re-transformation in xi_2
93  scalar_t jac2 = 2.0 / (1.0 - xi1);
94 
95  line_quad_t xi2_quad = telles_transform(m_quad_line, xi2_bar, zeta0 * jac2);
96 
97  // Fill the quadrature points on the triangle
98  for (size_t j = 0; j < xi2_quad.size(); ++j) {
99  scalar_t eta = (1.0 - xi1)*(xi2_quad[j].get_xi()(0) + 1.0)/2.0;
100  quad_tria[i*xi2_quad.size() + j].set_xi(xi_t(xi1, eta));
101  quad_tria[i*xi2_quad.size() + j].set_w(xi1_quad[i].get_w() / jac1 * xi2_quad[j].get_w() / jac2);
102  }
103  }
104 
105  return quad_tria;
106  }
107 
108 private:
109  line_quad_t const m_quad_line;
110 };
111 
112 
113 } // of namespace internal
114 
115 template <class TrialField, class Kernel, unsigned Order, class Enable = void>
117 
118 template <class TrialField, class Kernel, unsigned Order>
119 class nearly_singular_collocational_telles<TrialField, Kernel, Order,
120  typename std::enable_if<
121  element_traits::is_surface_element<typename TrialField::elem_t>::value
122  >::type>
123 {
124 public:
126  enum {
127  order = Order,
128  };
129 
131  typedef TrialField trial_field_t;
133  typedef typename trial_field_t::elem_t elem_t;
134 
136  typedef typename elem_t::domain_t domain_t;
138  typedef typename domain_t::xi_t xi_t;
140  typedef typename elem_t::scalar_t scalar_t;
141 
143  typedef typename elem_t::x_t x_t;
144 
146  typedef typename trial_field_t::nset_t trial_nset_t;
148  typedef typename trial_nset_t::shape_t trial_n_shape_t;
149 
151  typedef Kernel kernel_t;
152 
157 
160 
162  typedef typename semi_block_product_result_type<
163  typename kernel_t::result_t, trial_n_shape_t
164  >::type total_result_t;
165 
166  // class for computing the transformed quadrature
167  typedef internal::telles_transformer<domain_t> transformer_t;
168 
169 
171 
177  field_base<trial_field_t> const &trial_field,
178  kernel_base<kernel_t> const &kernel)
179  : m_elem(trial_field.get_elem())
180  , m_kernel(kernel)
181  , m_transformer(Order)
182  {
183  }
184 
185  template <class result_t>
186  void integrate(result_t &&I, test_input_t const &tsi)
187  {
188  // the reference point
189  x_t x0 = tsi.get_x();
190 
191  // perform inverse mapping to obtain image of reference point on element
192  double tol = 1e-6;
193  unsigned max_iter = 100;
194  // inverse mapping constrained inside element
195  inverse_mapping<elem_t> im(m_elem, true);
196  if (!im.eval(x0, tol, max_iter))
197  throw std::runtime_error("Could not perform inverse mapping");
198  auto res = im.get_result();
199  m_xi0 = res.topRows(xi_t::RowsAtCompileTime);
200  m_zeta = res(xi_t::RowsAtCompileTime);
201 
202  // perform telles transform
203  quad_t quad_telles = m_transformer.transform(m_xi0, m_zeta);
204 
205  for (auto q : quad_telles)
206  {
207  xi_t xi = q.get_xi();
208  double w = q.get_w();
209  w_trial_input_t wtri(m_elem, xi);
210  auto N = trial_nset_t::template eval_shape<0>(xi);
211  I += semi_block_product(m_kernel(tsi, wtri) * wtri.get_jacobian() * w, N);
212  }
213 
214  } // end of function integrate
215 
216 private:
217  elem_t const &m_elem;
218  kernel_base<kernel_t> const &m_kernel;
219  xi_t m_xi0;
220  double m_zeta;
221  transformer_t m_transformer;
222 };
223 
224 } // end of namespace NiHu
225 
226 #endif /* NIHU_NEARLY_SINGULAR_COLLOCATIONAL_HPP_INCLUDED */
NiHu::volume_element
class describing a volume element that has no normal vector
Definition: element.hpp:455
NiHu::gaussian_quadrature< domain_t >
NiHu::volume_element::x_t
element_traits::location_value_type< Derived, 0 >::type x_t
type of the element's physical location variable
Definition: element.hpp:220
NiHu::telles_transform
QuadDerived telles_transform(quadrature_base< QuadDerived > const &q, typename quadrature_traits< QuadDerived >::domain_t::xi_t const &eta_bar, typename quadrature_traits< QuadDerived >::domain_t::scalar_t const &d=typename quadrature_traits< QuadDerived >::domain_t::scalar_t())
Telles third order polynomial transform.
Definition: telles_1987.hpp:44
NiHu::nearly_singular_collocational_telles< TrialField, Kernel, Order, typename std::enable_if< element_traits::is_surface_element< typename TrialField::elem_t >::value >::type >::w_trial_input_t
weighted_input< trial_input_t, elem_t >::type w_trial_input_t
the kernel's weighted trial input type
Definition: nearly_singular_collocational_telles.hpp:159
NiHu::nearly_singular_collocational_telles< TrialField, Kernel, Order, typename std::enable_if< element_traits::is_surface_element< typename TrialField::elem_t >::value >::type >::test_input_t
kernel_traits< kernel_t >::test_input_t test_input_t
the kernel's test input type
Definition: nearly_singular_collocational_telles.hpp:154
NiHu::semi_block_product
semi_block_product_result_type< mat, rightDerived >::type semi_block_product(mat const &m, Eigen::MatrixBase< rightDerived > const &r)
compute semi block product of a matrix and a vector m * v^T
Definition: block_product.hpp:194
NiHu::nearly_singular_collocational_telles< TrialField, Kernel, Order, typename std::enable_if< element_traits::is_surface_element< typename TrialField::elem_t >::value >::type >::trial_field_t
TrialField trial_field_t
the trial field type
Definition: nearly_singular_collocational_telles.hpp:131
NiHu::nearly_singular_collocational_telles< TrialField, Kernel, Order, typename std::enable_if< element_traits::is_surface_element< typename TrialField::elem_t >::value >::type >::total_result_t
semi_block_product_result_type< typename kernel_t::result_t, trial_n_shape_t >::type total_result_t
value type of the integral result
Definition: nearly_singular_collocational_telles.hpp:164
NiHu::nearly_singular_collocational_telles< TrialField, Kernel, Order, typename std::enable_if< element_traits::is_surface_element< typename TrialField::elem_t >::value >::type >::kernel_t
Kernel kernel_t
the kernel type
Definition: nearly_singular_collocational_telles.hpp:151
NiHu::nearly_singular_collocational_telles< TrialField, Kernel, Order, typename std::enable_if< element_traits::is_surface_element< typename TrialField::elem_t >::value >::type >::trial_input_t
kernel_traits< kernel_t >::trial_input_t trial_input_t
the kernel's trial input type
Definition: nearly_singular_collocational_telles.hpp:156
NiHu::nearly_singular_collocational_telles< TrialField, Kernel, Order, typename std::enable_if< element_traits::is_surface_element< typename TrialField::elem_t >::value >::type >::scalar_t
elem_t::scalar_t scalar_t
the geometrical scalar type
Definition: nearly_singular_collocational_telles.hpp:140
NiHu::kernel_base< kernel_t >
NiHu::kernel_traits
traits class of a kernel
Definition: kernel.hpp:71
NiHu::nearly_singular_collocational_telles< TrialField, Kernel, Order, typename std::enable_if< element_traits::is_surface_element< typename TrialField::elem_t >::value >::type >::elem_t
trial_field_t::elem_t elem_t
the element type
Definition: nearly_singular_collocational_telles.hpp:133
NiHu::nearly_singular_collocational_telles
Definition: nearly_singular_collocational_telles.hpp:116
NiHu::nearly_singular_collocational_telles< TrialField, Kernel, Order, typename std::enable_if< element_traits::is_surface_element< typename TrialField::elem_t >::value >::type >::trial_nset_t
trial_field_t::nset_t trial_nset_t
shape function set type
Definition: nearly_singular_collocational_telles.hpp:146
NiHu::nearly_singular_collocational_telles< TrialField, Kernel, Order, typename std::enable_if< element_traits::is_surface_element< typename TrialField::elem_t >::value >::type >::xi_t
domain_t::xi_t xi_t
the reference coordinate vector type
Definition: nearly_singular_collocational_telles.hpp:138
NiHu::nearly_singular_collocational_telles< TrialField, Kernel, Order, typename std::enable_if< element_traits::is_surface_element< typename TrialField::elem_t >::value >::type >::x_t
elem_t::x_t x_t
the physical coordinate vector type
Definition: nearly_singular_collocational_telles.hpp:143
NiHu::semi_block_product_result_type
metafunction returning the value type of a semi block product
Definition: block_product.hpp:180
NiHu::field_base
CRTP base class of all fields.
Definition: field.hpp:111
NiHu::domain_base< line_domain >::xi_t
space_t::location_t xi_t
coordinate vector type
Definition: domain.hpp:91
telles_1987.hpp
Implementation of Telles' quadrature transform method.
NiHu::volume_element::domain_t
typename base_t::domain_t domain_t
the domain type
Definition: element.hpp:637
location_normal.hpp
implementation of location and normal kernel inputs
NiHu::nearly_singular_collocational_telles< TrialField, Kernel, Order, typename std::enable_if< element_traits::is_surface_element< typename TrialField::elem_t >::value >::type >::trial_n_shape_t
trial_nset_t::shape_t trial_n_shape_t
the shape function vector type
Definition: nearly_singular_collocational_telles.hpp:148
NiHu::nearly_singular_collocational_telles< TrialField, Kernel, Order, typename std::enable_if< element_traits::is_surface_element< typename TrialField::elem_t >::value >::type >::nearly_singular_collocational_telles
nearly_singular_collocational_telles(field_base< trial_field_t > const &trial_field, kernel_base< kernel_t > const &kernel)
constructor
Definition: nearly_singular_collocational_telles.hpp:176
NiHu::nearly_singular_collocational_telles< TrialField, Kernel, Order, typename std::enable_if< element_traits::is_surface_element< typename TrialField::elem_t >::value >::type >::domain_t
elem_t::domain_t domain_t
the original reference domain type
Definition: nearly_singular_collocational_telles.hpp:136
NiHu::inverse_mapping
mapping from physical to intrinsic coordinates
Definition: inverse_mapping.hpp:23
weighted_input.hpp
implementation of metafunction NiHu::weighted_input
NiHu::weighted_input
the weigthed input is an extended input that contains the jacobian a well
Definition: weighted_input.hpp:19