NiHu  2.0
integral_operator.hpp
Go to the documentation of this file.
1 // This file is a part of NiHu, a C++ BEM template library.
2 //
3 // Copyright (C) 2012-2014 Peter Fiala <fiala@hit.bme.hu>
4 // Copyright (C) 2012-2014 Peter Rucz <rucz@hit.bme.hu>
5 //
6 // This program is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
22 
23 #ifndef INTEGRAL_OPERATOR_HPP_INCLUDED
24 #define INTEGRAL_OPERATOR_HPP_INCLUDED
25 
26 #include "../util/crtp_base.hpp"
27 #include "function_space.hpp"
28 #include "single_integral.hpp"
29 #include "double_integral.hpp"
30 #include "integral_transform_forward.hpp"
31 
32 namespace NiHu
33 {
34 
35 
39 template <class Derived>
41 
45 template <class Derived>
47 {
48 public:
50 
53 
55  template <class TestField, class TrialField>
56  struct wr_result_type : traits_t::template wr_result_type<TestField, TrialField> {};
57 
65  template <class TestField, class TrialField, class OnSameMesh>
68  field_base<TestField> const &test_field,
69  field_base<TrialField> const &trial_field,
70  OnSameMesh) const
71  {
72  return derived().derived_eval_on_fields(test_field, trial_field, OnSameMesh());
73  }
74 
79  template <class FuncSpace>
81  Derived,
82  typename std::enable_if<is_function_space<FuncSpace>::value, FuncSpace>::type
83  >
84  operator[](FuncSpace &&funcspace)
85  {
87  derived(),
88  std::forward<FuncSpace>(funcspace));
89  }
90 };
91 
93 template <class IntOp>
94 struct is_integral_operator : std::is_base_of<
95  integral_operator_base<typename std::decay<IntOp>::type>,
96  typename std::decay<IntOp>::type
97 >{};
98 
99 
100 // forward declaration
101 template <class Scalar, class IntOp>
103 
104 
106 template <class Scalar, class IntOp>
108 {
110  template <class TestField, class TrialField>
111  struct wr_result_type : plain_type<
112  typename product_type<
113  Scalar,
114  typename integral_operator_traits<
115  typename std::decay<IntOp>::type
116  >::template wr_result_type<TestField, TrialField>::type
117  >::type
118  > {};
119 
121  static bool const is_local = integral_operator_traits<
122  typename std::decay<IntOp>::type
123  >::is_local;
124 };
125 
126 
131 template <class Scalar, class IntOp>
133  public integral_operator_base<scaled_integral_operator<Scalar, IntOp> >
134 {
135 public:
138 
139 
145  Scalar &&scalar,
146  IntOp &&parent) :
147  m_scalar(std::forward<Scalar>(scalar)),
148  m_parent(std::forward<IntOp>(parent))
149  {
150  }
151 
159  template <class TestField, class TrialField, class OnSameMesh>
160  typename base_t::template wr_result_type<TestField, TrialField>::type
162  field_base<TestField> const &test_field,
163  field_base<TrialField> const &trial_field,
164  OnSameMesh) const
165  {
166  return m_scalar * m_parent.eval_on_fields(test_field, trial_field, OnSameMesh());
167  }
168 
169 private:
171  Scalar m_scalar;
173  IntOp m_parent;
174 };
175 
176 
184 template <class Scalar, class IntOp>
185 scaled_integral_operator<
186  Scalar,
187  typename std::enable_if<is_integral_operator<IntOp>::value, IntOp>::type
188 >
189  operator*(Scalar &&scalar, IntOp &&intop)
190 {
192  std::forward<Scalar>(scalar),
193  std::forward<IntOp>(intop));
194 }
195 
196 
197 
198 template <class LhsOp, class RhsOp>
200 
201 template <class LhsOp, class RhsOp>
203 {
205  template <class TestField, class TrialField>
206  struct wr_result_type : plain_type<
207  typename sum_type<
208  typename integral_operator_traits<
209  typename std::decay<LhsOp>::type
210  >::template wr_result_type<TestField, TrialField>::type,
211  typename integral_operator_traits<
212  typename std::decay<RhsOp>::type
213  >::template wr_result_type<TestField, TrialField>::type
214  >::type
215  > {};
216 
218  static bool const is_local = integral_operator_traits<
219  typename std::decay<LhsOp>::type
220  >::is_local && integral_operator_traits<
221  typename std::decay<RhsOp>::type
222  >::is_local;
223 
224  static_assert(
225  integral_operator_traits<typename std::decay<LhsOp>::type>::is_local ==
226  integral_operator_traits<typename std::decay<RhsOp>::type>::is_local
227  , "You cannot form the sum of operators with different locality");
228 };
229 
230 
231 template <class LhsOp, class RhsOp>
232 class sum_integral_operator :
233  public integral_operator_base<sum_integral_operator<LhsOp, RhsOp> >
234 {
235 public:
236  static_assert(
237  integral_operator_traits<typename std::decay<LhsOp>::type>::is_local ==
238  integral_operator_traits<typename std::decay<RhsOp>::type>::is_local
239  , "You cannot form the sum of operators with different locality");
240 
243 
244 
246  LhsOp &&lhs,
247  RhsOp &&rhs) :
248  m_lhs(std::forward<LhsOp>(lhs)),
249  m_rhs(std::forward<RhsOp>(rhs))
250  {
251  }
252 
260  template <class TestField, class TrialField, class OnSameMesh>
261  typename base_t::template wr_result_type<TestField, TrialField>::type
263  field_base<TestField> const &test_field,
264  field_base<TrialField> const &trial_field,
265  OnSameMesh) const
266  {
267  return m_lhs.eval_on_fields(test_field, trial_field, OnSameMesh()) + m_rhs.eval_on_fields(test_field, trial_field, OnSameMesh());
268  }
269 
270 private:
272  LhsOp m_lhs;
274  RhsOp m_rhs;
275 };
276 
277 
278 template <class LhsOp, class RhsOp>
279 sum_integral_operator<
280  typename std::enable_if<is_integral_operator<LhsOp>::value, LhsOp>::type,
281  typename std::enable_if<is_integral_operator<RhsOp>::value, RhsOp>::type
282 >
283  operator+(LhsOp &&lhs, RhsOp &&rhs)
284 {
285  return sum_integral_operator<LhsOp, RhsOp>(
286  std::forward<LhsOp>(lhs),
287  std::forward<RhsOp>(rhs));
288 }
289 
290 
291 
292 // forward declaration
293 class identity_integral_operator;
294 
296 template <>
298 {
299  template <class TestField, class TrialField>
300  struct wr_result_type
301  {
303  };
304 
306  static bool const is_local = true;
307 };
308 
311  public integral_operator_base<identity_integral_operator>
312 {
313 public:
316 
324  template <class TestField, class TrialField, class OnSameMesh = std::false_type>
325  typename base_t::template wr_result_type<TestField, TrialField>::type
327  field_base<TestField> const &test_field,
328  field_base<TrialField> const &trial_field,
329  OnSameMesh) const
330  {
331  return single_integral<TestField, TrialField>::eval(test_field, trial_field);
332  }
333 };
334 
335 
336 
337 // forward declaration
338 template <class Kernel>
340 
344 template <class Kernel>
346 {
348  template <class TestField, class TrialField>
349  struct wr_result_type
350  {
351  typedef typename double_integral<typename std::decay<Kernel>::type, TestField, TrialField>::result_t type;
352  };
353 
355  static bool const is_local = false;
356 };
357 
358 
359 
363 template <class Kernel>
364 class integral_operator :
365  public integral_operator_base<integral_operator<Kernel> >
366 {
367 public:
370 
372  typedef typename std::decay<Kernel>::type kernel_t;
373 
377  integral_operator(Kernel &&kernel) :
378  m_kernel(std::forward<Kernel>(kernel))
379  {
380  }
381 
385  Kernel get_kernel(void) const
386  {
387  return m_kernel;
388  }
389 
397  template <class TestField, class TrialField, class OnSameMesh>
398  typename base_t::template wr_result_type<TestField, TrialField>::type
400  field_base<TestField> const &test_field,
401  field_base<TrialField> const &trial_field,
402  OnSameMesh) const
403  {
405  m_kernel, test_field, trial_field, OnSameMesh());
406  }
407 
408 private:
410  Kernel m_kernel;
411 };
412 
413 
419 template <class Kernel>
420 integral_operator<Kernel>
421  create_integral_operator(Kernel &&kernel)
422 {
423  return integral_operator<Kernel>(std::forward<Kernel>(kernel));
424 }
425 
426 } // end of namespace NiHu
427 
428 #endif
429 
NiHu::create_integral_operator
integral_operator< Kernel > create_integral_operator(Kernel &&kernel)
factory function of an integral operator
Definition: integral_operator.hpp:421
NiHu::integral_operator_base::eval_on_fields
wr_result_type< TestField, TrialField >::type eval_on_fields(field_base< TestField > const &test_field, field_base< TrialField > const &trial_field, OnSameMesh) const
sub-weighted residual on a test and a trial field
Definition: integral_operator.hpp:67
NiHu::integral_transform
Proxy class of a NiHu::integral_operator applied on a NiHu::function_space.
Definition: integral_transform.hpp:134
NiHu::double_integral
class evaluating double integrals of the weighted residual approach
Definition: double_integral.hpp:133
NiHu::integral_operator::integral_operator
integral_operator(Kernel &&kernel)
constructor from kernel
Definition: integral_operator.hpp:377
NiHu::sum_integral_operator::derived_eval_on_fields
base_t::template wr_result_type< TestField, TrialField >::type derived_eval_on_fields(field_base< TestField > const &test_field, field_base< TrialField > const &trial_field, OnSameMesh) const
evaluate a scaled integral operator on a test and a trial field
Definition: integral_operator.hpp:262
NiHu::single_integral::result_t
single_integral_traits< TestField, TrialField >::result_t result_t
the result matrix type
Definition: single_integral.hpp:213
NiHu::is_integral_operator
metafunction returning true if IntOp is an integral operator expression
Definition: integral_operator.hpp:94
NiHu::scalar
metafunction returning the scalar type
Definition: matrix_traits.hpp:66
NiHu::identity_integral_operator
The identity integral operator .
Definition: integral_operator.hpp:310
NiHu::identity_integral_operator::base_t
integral_operator_base< identity_integral_operator > base_t
CRTP base.
Definition: integral_operator.hpp:315
NiHu::integral_operator::base_t
integral_operator_base< integral_operator< Kernel > > base_t
the CRTP base class
Definition: integral_operator.hpp:369
NIHU_CRTP_HELPERS
#define NIHU_CRTP_HELPERS
define CRTP helper function
Definition: crtp_base.hpp:29
NiHu::scaled_integral_operator::scaled_integral_operator
scaled_integral_operator(Scalar &&scalar, IntOp &&parent)
constructor from a scalar and an integral operator instance
Definition: integral_operator.hpp:144
NiHu::sum_integral_operator
Definition: integral_operator.hpp:199
NiHu::integral_operator_base::operator[]
integral_transform< Derived, typename std::enable_if< is_function_space< FuncSpace >::value, FuncSpace >::type > operator[](FuncSpace &&funcspace)
apply the integral operator on a function space and create a NiHu::integral_transform
Definition: integral_operator.hpp:84
NiHu::integral_operator::kernel_t
std::decay< Kernel >::type kernel_t
template argument as nested type
Definition: integral_operator.hpp:372
single_integral.hpp
declaration of class single_integral
NiHu::plain_type
Plain object type of a class.
Definition: plain_type.hpp:45
NiHu::operator*
scaled_integral_operator< Scalar, typename std::enable_if< is_integral_operator< IntOp >::value, IntOp >::type > operator*(Scalar &&scalar, IntOp &&intop)
factory operator to create a scaled integral operator
Definition: integral_operator.hpp:189
NiHu::scaled_integral_operator
Proxy class representing an integral operator multiplied by a scalar.
Definition: integral_operator.hpp:102
NiHu::scaled_integral_operator::base_t
integral_operator_base< scaled_integral_operator< Scalar, IntOp > > base_t
the CRTP base class
Definition: integral_operator.hpp:137
NiHu::field_base
CRTP base class of all fields.
Definition: field.hpp:111
NiHu::integral_operator::derived_eval_on_fields
base_t::template wr_result_type< TestField, TrialField >::type derived_eval_on_fields(field_base< TestField > const &test_field, field_base< TrialField > const &trial_field, OnSameMesh) const
evaluate an integral operator on a test and a trial field
Definition: integral_operator.hpp:399
NiHu::integral_operator::get_kernel
Kernel get_kernel(void) const
return kernel (reference)
Definition: integral_operator.hpp:385
NiHu::integral_operator_base::traits_t
NIHU_CRTP_HELPERS typedef integral_operator_traits< Derived > traits_t
the traits class of the derived integral operator
Definition: integral_operator.hpp:52
NiHu::integral_operator_base::wr_result_type
metafunction obtained from the traits class
Definition: integral_operator.hpp:56
NiHu::identity_integral_operator::derived_eval_on_fields
base_t::template wr_result_type< TestField, TrialField >::type derived_eval_on_fields(field_base< TestField > const &test_field, field_base< TrialField > const &trial_field, OnSameMesh) const
evaluate an identity operator on a test and a trial field
Definition: integral_operator.hpp:326
NiHu::integral_operator_traits
traits class for an integral operator
Definition: integral_operator.hpp:40
function_space.hpp
declaration of class function_space
NiHu::single_integral::eval
static constexpr result_t eval(field_base< TestField > const &, field_base< TrialField > const &)
specialisation of single_integral::eval for the empty case
Definition: single_integral.hpp:218
NiHu::sum_integral_operator::base_t
integral_operator_base< sum_integral_operator< LhsOp, RhsOp > > base_t
the CRTP base class
Definition: integral_operator.hpp:239
double_integral.hpp
declaration of class double_integral and its specialisations
NiHu::scaled_integral_operator::derived_eval_on_fields
base_t::template wr_result_type< TestField, TrialField >::type derived_eval_on_fields(field_base< TestField > const &test_field, field_base< TrialField > const &trial_field, OnSameMesh) const
evaluate a scaled integral operator on a test and a trial field
Definition: integral_operator.hpp:161
NiHu::integral_operator_base
CRTP base of integral operator expressions.
Definition: integral_operator.hpp:46
NiHu::integral_operator
the general integral operator with an arbitrary kernel
Definition: integral_operator.hpp:339