FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
tensor_product_factory.hpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
6#pragma once
7
8// includes, FEAT
9#include <kernel/cubature/scalar/driver_factory.hpp>
10#include <kernel/cubature/rule.hpp>
11
12namespace FEAT
13{
14 namespace Cubature
15 {
16 template<typename Shape_>
17 class TensorProductDriver DOXY({});
18
19 template<>
20 class TensorProductDriver<Shape::Hypercube<1> >
21 {
22 public:
23 static int count(int num_points)
24 {
25 return num_points;
26 }
27
28 template<
29 typename Weight_,
30 typename Coord_,
31 typename Point_>
32 static void fill(
33 Rule<Shape::Hypercube<1>, Weight_, Coord_, Point_>& rule,
34 const Scalar::Rule<Weight_, Coord_>& scalar_rule)
35 {
36 for(int i(0); i < scalar_rule.get_num_points(); ++i)
37 {
38 rule.get_weight(i) = scalar_rule.get_weight(i);
39 rule.get_coord(i, 0) = scalar_rule.get_coord(i);
40 }
41 }
42 };
43
44 template<>
45 class TensorProductDriver<Shape::Hypercube<2> >
46 {
47 public:
48 static int count(int num_points)
49 {
50 return num_points * num_points;
51 }
52
53 template<
54 typename Weight_,
55 typename Coord_,
56 typename Point_>
57 static void fill(
58 Rule<Shape::Hypercube<2>, Weight_, Coord_, Point_>& rule,
59 const Scalar::Rule<Weight_, Coord_>& scalar_rule)
60 {
61 int num_points = scalar_rule.get_num_points();
62 for(int i(0); i < num_points; ++i)
63 {
64 for(int j(0); j < num_points; ++j)
65 {
66 int l = i*num_points + j;
67 rule.get_weight(l) = scalar_rule.get_weight(i) * scalar_rule.get_weight(j);
68 rule.get_coord(l, 0) = scalar_rule.get_coord(i);
69 rule.get_coord(l, 1) = scalar_rule.get_coord(j);
70 }
71 }
72 }
73 };
74
75 template<>
76 class TensorProductDriver<Shape::Hypercube<3> >
77 {
78 public:
79 static int count(int num_points)
80 {
81 return num_points * num_points * num_points;
82 }
83
84 template<
85 typename Weight_,
86 typename Coord_,
87 typename Point_>
88 static void fill(
89 Rule<Shape::Hypercube<3>, Weight_, Coord_, Point_>& rule,
90 const Scalar::Rule<Weight_, Coord_>& scalar_rule)
91 {
92 int num_points = scalar_rule.get_num_points();
93 for(int i(0); i < num_points; ++i)
94 {
95 for(int j(0); j < num_points; ++j)
96 {
97 for(int k(0); k < num_points; ++k)
98 {
99 int l = (i*num_points + j)*num_points + k;
100 rule.get_weight(l) = scalar_rule.get_weight(i) * scalar_rule.get_weight(j) * scalar_rule.get_weight(k);
101 rule.get_coord(l, 0) = scalar_rule.get_coord(i);
102 rule.get_coord(l, 1) = scalar_rule.get_coord(j);
103 rule.get_coord(l, 2) = scalar_rule.get_coord(k);
104 }
105 }
106 }
107 }
108 };
109
110 template<
111 typename ScalarDriver_,
112 typename Shape_>
114 {
115 public:
118
119 public:
120
121 template<
122 typename Weight_,
123 typename Coord_,
124 typename Point_>
125 static void create(
127 const Scalar::Rule<Weight_, Coord_>& scalar_rule)
128 {
129 int num_points = TensorProductDriverType::count(scalar_rule.get_num_points());
130#ifdef FEAT_CUBATURE_TENSOR_PREFIX
131 rule = Rule<Shape_, Weight_, Coord_, Point_>(num_points, "tensor:" + scalar_rule.get_name());
132#else
133 rule = Rule<Shape_, Weight_, Coord_, Point_>(num_points, scalar_rule.get_name());
134#endif // FEAT_CUBATURE_TENSOR_PREFIX
135 TensorProductDriverType::fill(rule, scalar_rule);
136 }
137
138 template<
139 typename Weight_,
140 typename Coord_,
141 typename Point_>
142 static bool create(
144 const String& name)
145 {
146 typedef Scalar::Rule<Weight_, Coord_> ScalarRuleType;
147
148#ifdef FEAT_CUBATURE_TENSOR_PREFIX
149 // try to find a colon within the string
150 String::size_type k = name.find_first_of(':');
151 if(k == name.npos)
152 return false;
153
154 // extract substrings until the colon
155 String head(name.substr(0, k));
156 String tail(name.substr(k + 1));
157
158 // check head - this is the name of the formula
159 if(head.trim().compare_no_case("tensor") != 0)
160 return false;
161
162 // call scalar factory to create the scalar rule
163 ScalarRuleType scalar_rule;
164 if(!ScalarFactoryType::create(scalar_rule, tail.trim()))
165 return false;
166#else
167 // call scalar factory to create the scalar rule
168 ScalarRuleType scalar_rule;
169 if(!ScalarFactoryType::create(scalar_rule, name))
170 return false;
171#endif // FEAT_CUBATURE_TENSOR_PREFIX
172
173 // convert scalar rule
174 create(rule, scalar_rule);
175 return true;
176 }
177
178 static String name()
179 {
180#ifdef FEAT_CUBATURE_TENSOR_PREFIX
181 return "tensor:" + ScalarFactoryType::name();
182#else
183 return ScalarFactoryType::name();
184#endif // FEAT_CUBATURE_TENSOR_PREFIX
185 }
186
187 template<typename Functor_>
188 static void alias(Functor_& functor)
189 {
190#ifdef FEAT_CUBATURE_TENSOR_PREFIX
191 AliasTensorPrefixFunctor<Functor_> prefix_functor(functor);
192 ScalarFactoryType::alias(prefix_functor);
193#else
194 ScalarFactoryType::alias(functor);
195#endif // FEAT_CUBATURE_TENSOR_PREFIX
196 }
197
199 private:
200#ifdef FEAT_CUBATURE_TENSOR_PREFIX
201 template<typename Functor_>
202 class AliasTensorPrefixFunctor
203 {
204 private:
205 Functor_& _functor;
206
207 public:
208 explicit AliasTensorPrefixFunctor(Functor_& functor) :
209 _functor(functor)
210 {
211 }
212
213 void alias(const String& name)
214 {
215 _functor.alias("tensor:" + name);
216 }
217
218 void alias(const String& name, int num_points)
219 {
220 _functor.alias("tensor:" + name, num_points);
221 }
222 };
223#endif // FEAT_CUBATURE_TENSOR_PREFIX
225 };
226
227 template<
228 typename ScalarDriver_,
229 typename Shape_,
230 bool variadic_ = ScalarDriver_::variadic>
231 class TensorProductFactory DOXY({});
232
233 template<
234 typename ScalarDriver_,
235 typename Shape_>
236 class TensorProductFactory<ScalarDriver_, Shape_, false> :
237 public TensorProductFactoryBase<ScalarDriver_, Shape_>
238 {
239 public:
241 typedef Shape_ ShapeType;
243 static constexpr bool variadic = false;
244 static constexpr int num_points = ScalarFactoryType::num_points;
245
246 public:
248 {
249 }
250
251 using BaseClass::create;
252
253 template<typename Weight_, typename Coord_, typename Point_>
254 static void create(Rule<Shape_, Weight_, Coord_, Point_>& rule)
255 {
256 // call scalar factory to create the scalar rule
258 ScalarFactoryType::create(scalar_rule);
259
260 // convert scalar rule
261 create(rule, scalar_rule);
262 }
263 };
264
265 template<
266 typename ScalarDriver_,
267 typename Shape_>
268 class TensorProductFactory<ScalarDriver_, Shape_, true> :
269 public TensorProductFactoryBase<ScalarDriver_, Shape_>
270 {
271 public:
273 typedef Shape_ ShapeType;
275 static constexpr bool variadic = true;
276 static constexpr int min_points = ScalarFactoryType::min_points;
277 static constexpr int max_points = ScalarFactoryType::max_points;
278
279 protected:
280 int _num_points;
281
282 public:
283 explicit TensorProductFactory(int num_points) :
284 _num_points(num_points)
285 {
286 }
287
288 using BaseClass::create;
289
290 template<typename Weight_, typename Coord_, typename Point_>
292 {
293 create(rule, _num_points);
294 }
295
296 template<typename Weight_, typename Coord_, typename Point_>
297 static void create(Rule<Shape_, Weight_, Coord_, Point_>& rule, int num_points)
298 {
299 // call scalar factory to create the scalar rule
301 ScalarFactoryType::create(scalar_rule, num_points);
302
303 // convert scalar rule
304 create(rule, scalar_rule);
305 }
306 };
307 } // namespace Cubature
308} // namespace FEAT
Cubature Rule class template.
Definition: rule.hpp:38
Scalar Cubature Driver-Factory class template.
Scalar Cubature Rule class template.
Definition: rule.hpp:39
String class implementation.
Definition: string.hpp:46
int compare_no_case(const String &other) const
Compares two strings without regard to case.
Definition: string.hpp:679
String trim(const String &charset) const
Trims the string.
Definition: string.hpp:327
FEAT namespace.
Definition: adjactor.hpp:12
Hypercube shape tag struct template.
Definition: shape.hpp:64