Loading [MathJax]/extensions/tex2jax.js
Go to the documentation of this file.
25 #ifndef NIHU_DOUBLE_INTEGRAL_HPP_INCLUDED
26 #define NIHU_DOUBLE_INTEGRAL_HPP_INCLUDED
28 #include "../util/matrix_traits.hpp"
29 #include "../util/product_type.hpp"
30 #include "../util/plain_type.hpp"
31 #include "../util/block_product.hpp"
32 #include "../library/location_normal.hpp"
33 #include "../library/weighted_input.hpp"
34 #include "../tmp/control.hpp"
35 #include "../util/store_pattern.hpp"
45 #include "singular_integral_shortcut.hpp"
71 template <
class SingularityDimension>
76 template <
class result_t,
class Kernel,
class TestField,
class TrialField>
88 static bool printed =
false;
92 "Singular shortcut switch called for mtch dim: " <<
94 ", sing val: " << SingularityDimension::value << std::endl;
99 result, kernel, test_field, trial_field, mtch);
110 template <
class Kernel,
class TestField,
class TrialField>
115 typename TestField::nset_t::shape_t,
116 typename Kernel::result_t,
117 typename TrialField::nset_t::shape_t
130 class Kernel,
class TestField,
class TrialField,
142 template <
class Kernel,
class TestField,
class TrialField>
148 typedef std::true_type WITH_SINGULARITY_CHECK;
149 typedef std::false_type WITHOUT_SINGULARITY_CHECK;
180 template <
class dual_iterator_t>
190 for (; it != end; ++it)
196 test_field.eval(it.get_first()->get_xi()) *
197 (test_input.get_jacobian() * it.get_first()->get_w()),
198 kernel(test_input, trial_input),
199 trial_field.eval(it.get_second()->get_xi()) *
200 (trial_input.get_jacobian() * it.get_second()->get_w())
212 template <
class singular_accelerator_t,
class dummy>
213 struct eval_singular_on_accelerator
224 template <
class singular_iterator_t>
230 singular_iterator_t begin,
231 singular_iterator_t end)
233 for (; begin != end; ++begin)
239 test_field.eval(begin.get_test_quadrature_elem().get_xi()) *
240 (test_input.get_jacobian() * begin.get_test_quadrature_elem().get_w()),
241 kernel(test_input, trial_input),
242 trial_field.eval(begin.get_trial_quadrature_elem().get_xi()) *
243 (trial_input.get_jacobian() * begin.get_trial_quadrature_elem().get_w())
254 template <
class dummy>
260 template <
class singular_iterator_t>
269 throw std::runtime_error(
"Invalid general singular quadrature");
283 WITHOUT_SINGULARITY_CHECK,
289 #if NIHU_MEX_DEBUGGING
290 static bool printed =
false;
293 mexPrintf(
"double_integral::eval without singularity check called on elements %d <- %d\n",
310 TestField, TrialField,
311 typename Kernel::estimator_t
312 >::eval(test_field, trial_field);
314 auto acc(create_dual_field_type_accelerator(
315 test_store_t::get_data()[degree], trial_store_t::get_data()[degree],
iteration::diadic()));
317 return eval_on_accelerator(
318 result, kernel, test_field, trial_field, acc.begin(), acc.end());
330 WITH_SINGULARITY_CHECK,
340 if (mtch.get_match_dimension() == -1)
341 return eval(WITHOUT_SINGULARITY_CHECK(), result, kernel, test_field, trial_field);
346 if (!tmp::call_until<
347 possible_match_types,
354 >(result, kernel, test_field, trial_field, mtch))
355 std::cerr <<
"UNHANDLED GALERKIN SINGULARITY TYPE: " << mtch.get_match_dimension() << std::endl;
367 template <
class OnSameMesh>
374 static bool const sing_check_needed =
380 return eval(std::integral_constant<bool, sing_check_needed>(),
381 result, kernel, test_field, trial_field);
394 template <
class Kernel,
class TestField,
class TrialField>
401 typedef std::true_type WITH_SINGULARITY_CHECK;
402 typedef std::false_type WITHOUT_SINGULARITY_CHECK;
445 template <
class dual_iterator_t>
451 dual_iterator_t first,
452 dual_iterator_t last)
454 for (; first != last; ++first)
468 first.get_first()->get_N() * (first.get_first()->get_w()),
469 kernel(test_input, trial_input),
470 trial_field.eval(first.get_second()->get_xi()) * (trial_input.get_jacobian() * first.get_second()->get_w())
483 template <
class singular_accelerator_t,
class dummy>
484 struct eval_singular_on_accelerator
499 singular_accelerator_t
const &sa)
501 for (
unsigned idx = 0; idx < test_nset_t::num_nodes; ++idx)
505 for (
auto const &q : sa.get_trial_quadrature(idx))
509 result.template block<kernel_rows, kernel_cols*trial_nset_t::num_nodes>(idx*kernel_rows, 0)
511 kernel(collocation_point, trial_input),
512 trial_field.eval(q.get_xi()) * trial_input.get_jacobian() * q.get_w()
524 template <
class dummy>
539 throw std::runtime_error(
"Invalid quadrature returned by eval_singular_on_accelerator");
553 WITHOUT_SINGULARITY_CHECK,
561 kernel, test_field, trial_field))
563 result, kernel, test_field, trial_field);
567 TestField, TrialField,
568 typename Kernel::estimator_t
569 >::eval(test_field, trial_field);
571 #if NIHU_MEX_DEBUGGING
572 static bool printed =
false;
575 mexPrintf(
"double_integral::eval without singularity check called on elements %d <- %d\n",
577 mexPrintf(
"Regular integral with degree %d\n", degree);
583 throw std::out_of_range(
"Too high quadrature degree selected for collocational integration");
593 auto acc(create_dual_field_type_accelerator(
594 test_store_t::get_data()[degree], trial_store_t::get_data()[degree],
iteration::diadic()));
596 return eval_on_accelerator(
597 result, kernel, test_field, trial_field, acc.begin(), acc.end());
609 WITH_SINGULARITY_CHECK,
618 if (mtch.get_match_dimension() == -1)
619 return eval(WITHOUT_SINGULARITY_CHECK(), result, kernel, test_field, trial_field);
623 static bool printed =
false;
625 std::cout <<
"Now checking singular shortcuts" << std::endl;
630 if (!tmp::call_until<
631 possible_match_types,
638 >(result, kernel, test_field, trial_field, mtch))
640 std::cerr <<
"UNHANDLED COLLOCATIONAL SINGULARITY TYPE: " << mtch.get_match_dimension() << std::endl;
659 template <
class OnSameMesh>
670 static bool const sing_check_needed =
673 #if NIHU_MEX_DEBUGGING
674 static bool printed =
false;
685 std::integral_constant<bool, sing_check_needed>(),
686 result, kernel, test_field, trial_field);
689 for (
unsigned corner_idx = 0; corner_idx < num_test_corners; ++corner_idx)
691 double weight = test_field.get_corner_angle(corner_idx);
693 result.template block<kernel_rows, kernel_cols*trial_nset_t::num_nodes>(corner_idx*kernel_rows, 0) *= weight;
708 template <
class Kernel,
class TestField,
class TrialField,
class SingularityDimension,
class Enable>
712 typedef void unspecialised;
718 Kernel, TestField, TrialField, SingularityDimension
723 template <
class result_t>
724 static result_t &eval_impl(
732 return double_integral_t::template eval_singular_on_accelerator<singular_accelerator_t, void>::eval(
733 result, kernel, test_field, trial_field,
738 template <
class result_t>
739 static result_t &eval_impl(
748 static bool printed =
false;
750 std::cout <<
"General version of singular_integral_shortcut called" << std::endl;
754 #if NIHU_MEX_DEBUGGING
757 static bool printed =
false;
760 mexPrintf(
"General singular integral shortcut for collocation called\n");
765 return double_integral_t::template eval_singular_on_accelerator<singular_accelerator_t, void>::eval(
779 template <
class result_t>
787 #if NIHU_MEX_DEBUGGING
788 static bool printed =
false;
791 mexPrintf(
"General singular integral shortcut called\n");
795 return eval_impl(formalism_t(), result, kernel, test_field, trial_field, match);
static result_t & eval(result_t &result, kernel_base< Kernel > const &kernel, field_base< TestField > const &test_field, field_base< TrialField > const &trial_field, element_match const &match)
evaluate singular integral
kernel_traits_ns::result< Derived >::type result_t
the kernel result type
select a singular accelerator for a kernel and test and trial fields
element_match element_match_eval(field_base< test_field_t > const &test_field, field_base< trial_field_t > const &trial_field)
function to determine the overlapping state of two elements
general case when the test field is not Dirac
traits_t::result_t result_t
result type of the weighted residual
inner and outer iterators (Descartes)
kernel_traits_ns::test_input< Derived >::type test_input_t
kernel test input type
const elem_t & get_elem() const
return underlying element
TrialField::nset_t trial_nset_t
N-set of the trial field.
weighted_input< test_input_t, test_elem_t >::type w_test_input_t
weighted test input type of kernel
TrialField::elem_t trial_elem_t
type of the trial element
CRTP base class of all BEM kernels.
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
implementation of class NiHu::singular_accelerator
kernel_traits< Kernel >::trial_input_t trial_input_t
trial input type of kernel
implementation of class kernel and its traits
static result_t & eval(WITHOUT_SINGULARITY_CHECK, result_t &result, kernel_base< Kernel > const &kernel, field_base< TestField > const &test_field, field_base< TrialField > const &trial_field)
evaluate double integral of a kernel on specific fields without singularity check
return weak form formalism from the test and trial field types
kernel_traits< Kernel >::trial_input_t trial_input_t
trial input type of kernel
TestField::nset_t test_nset_t
N-set of the test field.
determine element singularities
metafunction returning the number of compile time columns
weighted_input< trial_input_t, trial_elem_t >::type w_trial_input_t
weighted trial input type of kernel
global constants governing some accuracy parameters
static result_t & eval(WITHOUT_SINGULARITY_CHECK, result_t &result, kernel_base< Kernel > const &kernel, field_base< TestField > const &test_field, field_base< TrialField > const &trial_field)
evaluate single integral of a kernel on specific fields without singularity check
block_product_result_type< typename TestField::nset_t::shape_t, typename Kernel::result_t, typename TrialField::nset_t::shape_t >::type result_t
result type of the weighted residual
Nearly singular integral general case.
TrialField::elem_t trial_elem_t
the trial elem type
int get_match_dimension() const
return singularity type
static result_t & eval(WITH_SINGULARITY_CHECK, result_t &result, kernel_base< Kernel > const &kernel, field_base< TestField > const &test_field, field_base< TrialField > const &trial_field)
evaluate double integral of a kernel on specific fields with singularity check
class evaluating double integrals of the weighted residual approach
kernel_traits< Kernel >::test_input_t test_input_t
test input type of kernel
matafunction assigning a match type vector to two fields
a shortcut for the user to define customised singular integral methods
static result_t eval(kernel_base< Kernel > const &kernel, field_base< TestField > const &test_field, field_base< TrialField > const &trial_field, OnSameMesh)
evaluate collocational integral on given fields
static result_t & eval(result_t &result, kernel_base< Kernel > const &kernel, field_base< TestField > const &test_field, field_base< TrialField > const &trial_field, singular_iterator_t begin, singular_iterator_t end)
evaluate double singular integral with selected singular accelerator
Defines the number of shape functions in the set.
return formalism from Test and Trial field types
CRTP base class of all fields.
kernel_traits< Kernel >::test_input_t test_input_t
test input type of kernel
weighted_input< trial_input_t, trial_elem_t >::type w_trial_input_t
weighted trial input type
static result_t & eval_on_accelerator(result_t &result, kernel_base< Kernel > const &kernel, field_base< TestField > const &test_field, field_base< TrialField > const &trial_field, dual_iterator_t first, dual_iterator_t last)
evaluate regular collocational integral with selected trial field accelerator
kernel_traits< Kernel >::quadrature_family_t quadrature_family_t
the quadrature family the kernel requires
block_product_result_type< leftDerived, mat, rightDerived >::type block_product(Eigen::MatrixBase< leftDerived > const &l, mat const &m, Eigen::MatrixBase< rightDerived > const &r)
compute a block product l * m * r^T
the weigthed input is an extended input that contains the jacobian a well
kernel_traits_ns::quadrature_family< Derived >::type quadrature_family_t
the far field asymptotic behaviour of the kernel
metafunction returning the number of compile time rows
static result_t & eval(result_t &result, kernel_base< Kernel > const &, field_base< TestField > const &, field_base< TrialField > const &, singular_iterator_t, singular_iterator_t)
evaluate double singular integral with the invalid accelerator
metafunction returning the value type of a block product
Storage class with a static member.
static result_t & eval(result_t &result, kernel_base< Kernel > const &, field_base< TestField > const &, field_base< TrialField > const &, invalid_singular_accelerator const &)
evaluate collocational singular integral with selected singular accelerator
kernel_traits< Kernel >::result_t kernel_result_t
result type of kernel
Estimate kernel complexity between two elements.
static const C & get_data(void)
Return reference to stored data.
const unsigned GLOBAL_MAX_ORDER
the maximal order of accelerated quadratures and field type accelerators
traits_t::result_t result_t
result type of the weighted residual
dofs_return_t get_dofs() const
return DOF vector
class describing the adjacency (match) state of two elements
kernel_traits< Kernel >::quadrature_family_t quadrature_family_t
the quadrature family the kernel requires
static result_t & eval_on_accelerator(result_t &result, kernel_base< Kernel > const &kernel, field_base< TestField > const &test_field, field_base< TrialField > const &trial_field, dual_iterator_t it, dual_iterator_t end)
evaluate regular double integral with selected accelerators
static result_t eval(kernel_base< Kernel > const &kernel, field_base< TestField > const &test_field, field_base< TrialField > const &trial_field, OnSameMesh)
evaluate double integral on given fields
TestField::elem_t test_elem_t
the test elem type
an invalid singular accelerator assigned to nonexisting integrals
static result_t & eval(result_t &result, kernel_base< Kernel > const &kernel, field_base< TestField > const &test_field, field_base< TrialField > const &trial_field, singular_accelerator_t const &sa)
evaluate collocational singular integral with selected singular accelerator
static result_t & eval(WITH_SINGULARITY_CHECK, result_t &result, kernel_base< Kernel > const &kernel, field_base< TestField > const &test_field, field_base< TrialField > const &trial_field)
evaluate single integral of a kernel on specific fields with singularity check
class to estimate kernel complexity between two fields
collocational case when the test field is Dirac
kernel_traits_ns::trial_input< Derived >::type trial_input_t
kernel trial input type
Acceleration of field types by storing shape functions for each quadrature point.