1 #ifndef NIHU_NEARLY_SINGULAR_COLLOCATIONAL_TELLES_HPP_INCLUDED
2 #define NIHU_NEARLY_SINGULAR_COLLOCATIONAL_TELLES_HPP_INCLUDED
4 #include "line_quad_store.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"
27 template <
class Domain>
28 struct telles_transformer
30 typedef Domain domain_t;
31 typedef gaussian_quadrature<domain_t> quad_t;
33 typedef typename domain_t::xi_t xi_t;
34 typedef typename domain_t::scalar_t scalar_t;
36 telles_transformer(
unsigned Order)
42 quad_t transform(xi_t
const& xi0, scalar_t
const& zeta0)
48 quad_t
const m_quad_orig;
60 struct telles_transformer<tria_domain>
62 typedef tria_domain domain_t;
63 typedef gaussian_quadrature<domain_t> tria_quad_t;
64 typedef gaussian_quadrature<line_domain> line_quad_t;
66 typedef typename domain_t::xi_t xi_t;
67 typedef typename domain_t::scalar_t scalar_t;
69 telles_transformer(
unsigned Order)
74 tria_quad_t transform(xi_t
const& xi0, scalar_t
const& zeta0)
76 tria_quad_t quad_tria;
77 size_t const n = m_quad_line.size();
78 quad_tria.resize(n*n);
87 for (
size_t i = 0; i < xi1_quad.size(); ++i) {
89 scalar_t xi1 = (1.0 + xi1_quad[i].get_xi()(0)) / 2.0;
93 scalar_t jac2 = 2.0 / (1.0 - xi1);
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);
109 line_quad_t
const m_quad_line;
115 template <
class TrialField,
class Kernel,
unsigned Order,
class Enable =
void>
118 template <
class TrialField,
class Kernel,
unsigned Order>
120 typename std::enable_if<
121 element_traits::is_surface_element<typename TrialField::elem_t>::value
133 typedef typename trial_field_t::elem_t
elem_t;
138 typedef typename domain_t::xi_t
xi_t;
167 typedef internal::telles_transformer<domain_t> transformer_t;
179 : m_elem(trial_field.get_elem())
181 , m_transformer(Order)
185 template <
class result_t>
186 void integrate(result_t &&I, test_input_t
const &tsi)
189 x_t x0 = tsi.get_x();
193 unsigned max_iter = 100;
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);
203 quad_t quad_telles = m_transformer.transform(m_xi0, m_zeta);
205 for (
auto q : quad_telles)
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);
218 kernel_base<kernel_t>
const &m_kernel;
221 transformer_t m_transformer;