BEM++  2.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Groups Pages
default_collection_of_kernels_imp.hpp
1 // Copyright (C) 2011-2012 by the BEM++ Authors
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in
11 // all copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 // THE SOFTWARE.
20 
21 #ifndef fiber_default_collection_of_kernels_imp_hpp
22 #define fiber_default_collection_of_kernels_imp_hpp
23 
24 #include "default_collection_of_kernels.hpp"
25 
26 #include "collection_of_3d_arrays.hpp"
27 #include "collection_of_4d_arrays.hpp"
28 #include "geometrical_data.hpp"
29 
30 #include <boost/utility/enable_if.hpp>
31 #include <stdexcept>
32 
33 #define FIBER_HAS_MEM_FUNC(func, name) \
34  template<typename T, typename Sign> \
35  struct name { \
36  typedef char yes[1]; \
37  typedef char no [2]; \
38  template <typename U, U> struct type_check; \
39  template <typename _1> static yes &chk(type_check<Sign, &_1::func> *); \
40  template <typename > static no &chk(...); \
41  static bool const value = sizeof(chk<T>(0)) == sizeof(yes); \
42  }
43 
44 namespace Fiber
45 {
46 
47 FIBER_HAS_MEM_FUNC(estimateRelativeScale, hasEstimateRelativeScale);
48 
49 //template <class Type>
50 //class TypeHasEstimateRelativeScale
51 //{
52 // // This type won't compile if the second template parameter isn't of type T,
53 // // so I can put a function pointer type in the first parameter and the function
54 // // itself in the second thus checking that the function has a specific signature.
55 // template <typename T, T> struct TypeCheck;
56 
57 // typedef char Yes;
58 // typedef long No;
59 
60 // // A helper struct to hold the declaration of the function pointer.
61 // // Change it if the function signature changes.
62 // template <typename T> struct EstimateRelativeScale
63 // {
64 // typedef typename Type::CoordinateType (T::*fptr)(typename Type::CoordinateType) const;
65 // };
66 
67 // template <typename T> static Yes HasEstimateRelativeScale(TypeCheck< typename EstimateRelativeScale<T>::fptr, &T::estimateRelativeScale >*);
68 // template <typename T> static No HasEstimateRelativeScale(...);
69 
70 //public:
71 // static bool const value = (sizeof(HasEstimateRelativeScale<Type>(0)) == sizeof(Yes));
72 //};
73 
74 
75 template<typename Functor>
76 typename boost::enable_if<hasEstimateRelativeScale<Functor,
77  typename Functor::CoordinateType(Functor::*)(typename Functor::CoordinateType) const>,
78  typename Functor::CoordinateType>::type
79 estimateRelativeScaleInternal(const Functor& functor,
80  typename Functor::CoordinateType distance)
81 {
82  return functor.estimateRelativeScale(distance);
83 }
84 
85 template<typename Functor>
86 typename boost::disable_if<hasEstimateRelativeScale<Functor,
87  typename Functor::CoordinateType(Functor::*)(typename Functor::CoordinateType) const>,
88  typename Functor::CoordinateType>::type
89 estimateRelativeScaleInternal(const Functor& functor,
90  typename Functor::CoordinateType distance)
91 {
92  return 1.;
93 }
94 
95 //template<typename Functor>
96 //typename boost::enable_if<TypeHasEstimateRelativeScale<Functor>,
97 // typename Functor::CoordinateType>::type
98 //estimateRelativeScaleInternal(const Functor& functor,
99 // typename Functor::CoordinateType distance)
100 //{
101 // // std::cout << "true impl" << std::endl;
102 // return functor.estimateRelativeScale(distance);
103 //}
104 
105 //template<typename Functor>
106 //typename boost::disable_if<TypeHasEstimateRelativeScale<Functor>,
107 // typename Functor::CoordinateType>::type
108 //estimateRelativeScaleInternal(const Functor& functor,
109 // typename Functor::CoordinateType distance)
110 //{ // std::cout << "fallback" << std::endl;
111 // return 1.;
112 //}
113 
114 template <typename Functor>
116  size_t& testGeomDeps, size_t& trialGeomDeps) const
117 {
118  m_functor.addGeometricalDependencies(testGeomDeps, trialGeomDeps);
119 }
120 
121 template <typename Functor>
123  const GeometricalData<CoordinateType>& testGeomData,
124  const GeometricalData<CoordinateType>& trialGeomData,
125  CollectionOf3dArrays<ValueType>& result) const
126 {
127  assert(testGeomData.pointCount() == trialGeomData.pointCount());
128 
129  const size_t pointCount = testGeomData.pointCount();
130  const size_t kernelCount = m_functor.kernelCount();
131  result.set_size(kernelCount);
132  for (size_t k = 0; k < kernelCount; ++k)
133  result[k].set_size(m_functor.kernelRowCount(k),
134  m_functor.kernelColCount(k),
135  pointCount);
136 
137  for (size_t p = 0; p < pointCount; ++p)
138  m_functor.evaluate(testGeomData.const_slice(p),
139  trialGeomData.const_slice(p),
140  result.slice(p).self());
141 }
142 
143 template <typename Functor>
144 void DefaultCollectionOfKernels<Functor>::evaluateOnGrid(
145  const GeometricalData<CoordinateType>& testGeomData,
146  const GeometricalData<CoordinateType>& trialGeomData,
147  CollectionOf4dArrays<ValueType>& result) const
148 {
149  const size_t testPointCount = testGeomData.pointCount();
150  const size_t trialPointCount = trialGeomData.pointCount();
151  const size_t kernelCount = m_functor.kernelCount();
152  result.set_size(kernelCount);
153  for (size_t k = 0; k < kernelCount; ++k)
154  result[k].set_size(m_functor.kernelRowCount(k),
155  m_functor.kernelColCount(k),
156  testPointCount,
157  trialPointCount);
158 
159 #pragma ivdep
160  for (size_t trialIndex = 0; trialIndex < trialPointCount; ++trialIndex)
161  for (size_t testIndex = 0; testIndex < testPointCount; ++testIndex)
162  m_functor.evaluate(testGeomData.const_slice(testIndex),
163  trialGeomData.const_slice(trialIndex),
164  result.slice(testIndex, trialIndex).self());
165 }
166 
167 template <typename Functor>
168 std::pair<const char*, int>
170  throw std::runtime_error("DefaultCollectionOfKernels::evaluateClCode(): "
171  "not implemented yet");
172 }
173 
174 
175 template <typename Functor>
176 typename DefaultCollectionOfKernels<Functor>::CoordinateType
178 estimateRelativeScale(CoordinateType distance) const
179 {
180  return estimateRelativeScaleInternal(m_functor, distance);
181 }
182 
183 } // namespace Fiber
184 
185 #endif
virtual std::pair< const char *, int > evaluateClCode() const
Currently unused.
Definition: default_collection_of_kernels_imp.hpp:169
Storage of geometrical data.
Definition: geometrical_data.hpp:54
Definition: collection_of_3d_arrays.hpp:39
virtual void addGeometricalDependencies(size_t &testGeomDeps, size_t &trialGeomDeps) const
Retrieve types of geometrical data on which the kernels depend.
Definition: default_collection_of_kernels_imp.hpp:115
Default implementation of a collection of kernels.
Definition: default_collection_of_kernels.hpp:87