Rheolef  7.2
an efficient C++ finite element environment
space_constant.h
Go to the documentation of this file.
1 #ifndef _RHEOLEF_SPACE_CONSTANT_H
2 #define _RHEOLEF_SPACE_CONSTANT_H
23 // constants
24 
25 #include "rheolef/undeterminated.h"
26 #include "rheolef/field_expr_utilities.h"
27 #include <type_traits>
28 
29 // ---------------------------------------------------------------------------
30 // utility
31 // ---------------------------------------------------------------------------
32 
33 namespace rheolef { namespace details {
34 
35 // is_equal : used by type resolution and by is_symmetric
36 template <class T1, class T2> struct is_equal : std::false_type {};
37 template <class T> struct is_equal<T,T> : std::true_type {};
38 
39 // switch for a constant, or a pointer-to-function or a class-function:
40 template<class T> struct is_scalar : std::false_type {};
41 template<> struct is_scalar<int> : std::true_type {};
42 template<> struct is_scalar<const int> : std::true_type {};
43 template<> struct is_scalar<size_t> : std::true_type {};
44 template<> struct is_scalar<double> : std::true_type {};
45 #ifdef _RHEOLEF_HAVE_FLOAT128
46 template<> struct is_scalar<float128> : std::true_type {};
47 #endif // _RHEOLEF_HAVE_FLOAT128
48 
49 template<class T> struct is_point : std::false_type {};
50 template<class T> struct is_point<point_basic<T> > : std::true_type {};
51 
52 template<class T> struct is_tensor : std::false_type {};
53 template<class T> struct is_tensor<tensor_basic<T> > : std::true_type {};
54 
55 template<class T> struct is_tensor3 : std::false_type {};
56 template<class T> struct is_tensor3<tensor3_basic<T> > : std::true_type {};
57 
58 template<class T> struct is_tensor4 : std::false_type {};
59 template<class T> struct is_tensor4<tensor4_basic<T> > : std::true_type {};
60 
61 } // namespace details
62 // ---------------------------------------------------------------------------
63 // argument promote, for template expression (binders, etc)
64 // ---------------------------------------------------------------------------
65 namespace details {
66 template <class T1, class T2, class Sfinae = void>
68 template <class T1, class T2, class Sfinae = void>
70 
71 #define _RHEOLEF_field_promote_argument(tensor) \
72 template<class T1, class T2> \
73 struct field_promote_first_argument<tensor##_basic<T1>, T2, \
74  typename std::enable_if< \
75  is_rheolef_arithmetic<T1>::value \
76  && is_rheolef_arithmetic<T2>::value \
77  >::type \
78 > { \
79  using type = tensor##_basic<typename promote<T1,T2>::type>; }; \
80 template <class T1, class T2> \
81 struct field_promote_first_argument<T1,tensor##_basic<T2>, \
82  typename std::enable_if< \
83  is_rheolef_arithmetic<T1>::value \
84  && is_rheolef_arithmetic<T2>::value \
85  >::type \
86 > { \
87  using type = typename promote<T1,T2>::type; }; \
88 template <class T1, class T2> \
89 struct field_promote_second_argument<tensor##_basic<T1>, T2, \
90  typename std::enable_if< \
91  is_rheolef_arithmetic<T1>::value \
92  && is_rheolef_arithmetic<T2>::value \
93  >::type \
94 > { \
95  using type = typename promote<T1,T2>::type; }; \
96 template <class T1, class T2> \
97 struct field_promote_second_argument<T1,tensor##_basic<T2>, \
98  typename std::enable_if< \
99  is_rheolef_arithmetic<T1>::value \
100  && is_rheolef_arithmetic<T2>::value \
101  >::type \
102 > { \
103  using type = tensor##_basic<typename promote<T1,T2>::type>; };
104 
109 #undef _RHEOLEF_field_promote_argument
110 
111 } // namespace details
112 // -------------------------------------------------------------
113 // coordinate system helper
114 // -------------------------------------------------------------
115 namespace space_constant {
116 
117 typedef size_t size_type;
118 
119 typedef enum {
123  last_coord_sys = 3
125 
129 
130 // -------------------------------------------------------------
131 // multi-component field support
132 // -------------------------------------------------------------
133 typedef enum {
134  scalar = 0,
135  vector = 1,
136  tensor = 2, // symmetric, D_ij
138  tensor3 = 4, // unsymmetric, G_ijk
139  tensor4 = 5, // symmetric, A_ijkl
140  mixed = 6,
141  last_valued = 7
143 
144 const std::string& valued_name (valued_type tag);
145 valued_type valued_tag (const std::string& name);
146 
149  size_type d,
151 
153  const std::string& valued,
154  size_type d,
156 
157 // convert a type to the enum valued_tag:
158 // size_t tag = valued_tag_traits<T>::value;
159 template<class T> struct valued_tag_traits { static const valued_type value = scalar; };
160 template<class T> struct valued_tag_traits<point_basic<T> > { static const valued_type value = vector; };
161 template<class T> struct valued_tag_traits<tensor_basic<T> > { static const valued_type value = tensor; };
162 template<class T> struct valued_tag_traits<tensor3_basic<T> > { static const valued_type value = tensor3; };
163 template<class T> struct valued_tag_traits<tensor4_basic<T> > { static const valued_type value = tensor4; };
164 template<class T> struct valued_tag_traits<undeterminated_basic<T> > { static const valued_type value = last_valued; };
165 
166 // convert an enum valued_tag to the type based on T:
167 // typedef typename valued_type_traits<tag,T>::type valued_t;
168 //
169 template<int Tag, class T> struct valued_type_traits { typedef undeterminated_basic<T> type; };
170 template<class T> struct valued_type_traits<scalar,T> { typedef T type; };
171 template<class T> struct valued_type_traits<vector,T> { typedef point_basic<T> type; };
172 template<class T> struct valued_type_traits<tensor,T> { typedef tensor_basic<T> type; };
173 template<class T> struct valued_type_traits<tensor3,T> { typedef tensor3_basic<T> type; };
174 template<class T> struct valued_type_traits<tensor4,T> { typedef tensor4_basic<T> type; };
175 template<class T> struct valued_type_traits<last_valued,T> { typedef undeterminated_basic<T> type; };
176 
177 // tensorial up and down helpers (for grad(expr))
179 template<class T> struct rank_down<point_basic<T> > { typedef T type; };
180 template<class T> struct rank_down<tensor_basic<T> > { typedef point_basic<T> type; };
181 template<class T> struct rank_down<tensor3_basic<T> > { typedef tensor_basic<T> type; };
182 template<class T> struct rank_down<tensor4_basic<T> > { typedef tensor3_basic<T> type; };
183 
184 template<class T> struct rank_up { typedef point_basic<typename scalar_traits<T>::type> type; };
185 template<class T> struct rank_up<point_basic<T> > { typedef tensor_basic<T> type; };
186 template<class T> struct rank_up<tensor_basic<T> > { typedef tensor3_basic<T> type; };
187 template<class T> struct rank_up<tensor3_basic<T> > { typedef tensor4_basic<T> type; };
189 
190 template<class T>
191 T contract_product (const T& a, const T& b) { return a*b; }
192 template<class T>
193 T contract_product (const point_basic<T>& a, const point_basic<T>& b) { return dot(a,b); }
194 template<class T>
195 T contract_product (const tensor_basic<T>& a, const tensor_basic<T>& b) { return ddot(a,b); }
196 
197 // -------------------------------------------------------------
198 // 2-tensor support
199 // -------------------------------------------------------------
203  size_type i,
204  size_type j);
205 
207  std::string valued,
208  std::string sys_coord,
209  size_type i,
210  size_type j);
211 
212 std::pair<size_type,size_type>
216  size_type i_comp);
217 
218 std::string
222  size_type i_comp);
223 
224 std::pair<size_type,size_type>
226  std::string valued,
227  std::string sys_coord,
228  size_type i_comp);
229 
230 std::string
232  std::string valued,
233  std::string sys_coord,
234  size_type i_comp);
235 
236 // -------------------------------------------------------------
237 // 4-tensor support
238 // -------------------------------------------------------------
239 size_type
241  valued_type valued,
243  size_type i,
244  size_type j,
245  size_type k,
246  size_type l);
247 
248 size_type
250  std::string valued,
251  std::string sys_coord,
252  size_type i,
253  size_type j,
254  size_type k,
255  size_type l);
256 
257 std::pair<std::pair<size_type,size_type>, std::pair<size_type,size_type> >
259  valued_type valued,
261  size_type i_comp);
262 
263 std::string
265  valued_type valued,
267  size_type i_comp);
268 
269 std::pair<std::pair<size_type,size_type>, std::pair<size_type,size_type> >
271  std::string valued,
272  std::string sys_coord,
273  size_type i_comp);
274 
275 std::string
277  std::string valued,
278  std::string sys_coord,
279  size_type i_comp);
280 
281 // -------------------------------------------------------------
282 // field*field & field/field valued_type computed at run time
283 // -------------------------------------------------------------
286 
287 
288 } // namespace space_constant
289 // --------------------------------------------------------------------------
290 // utility to determine whether a template arg is a function or a constant
291 // --------------------------------------------------------------------------
292 namespace details {
293  // build a function that returns a constant
294  template<class T1, class T2>
295  struct f_constant {
296  T2 operator() (const T1& x) const { return c; }
297  f_constant (const T2& c0) : c(c0) {}
298  const T2 c;
299  };
300  template<class F> struct is_vector_function :
301  and_type <
302  std::is_class<F>
303  ,is_point<typename F::result_type>
304  > {};
305  template<class T> struct is_vector_function<point_basic<T> (const point_basic<T>)>
306  : std::true_type {};
307 
308  template<class E> class field_nonlinear_expr;
309  template<class E> struct is_expr : std::false_type {};
310  template<class E> struct is_expr<field_nonlinear_expr<E> > : std::true_type {};
311 
312  template<class C>
313  struct is_constant :
314  or_type <
315  is_scalar<C>
316  ,is_point<C>
317  > {};
318 
319  template<class F>
320  struct is_function :
321  and_type <
322  or_type <
323  std::is_class<F>
324  ,std::is_pointer<F>
325  ,std::is_function<F>
326  >
327  ,not_type <
328  or_type <
329  is_scalar<F>
330  ,is_point<F>
331  ,is_expr<F>
332  >
333  >
334  >
335  {};
336  template<class F>
337  struct result_type {
339  };
340  template<class T, class R>
341  struct result_type<R(const point_basic<T>&)> {
342  typedef R type;
343  };
344  template<class T, class R>
345  struct result_type<R (*)(const point_basic<T>&)> {
346  typedef R type;
347  };
348  template<class Constant>
349  struct constant_promote { typedef Constant type; };
350  template<> struct constant_promote<int> { typedef Float type; };
351  template<> struct constant_promote<size_t> { typedef Float type; };
352 #ifdef _RHEOLEF_HAVE_FLOAT128
353  template<> struct constant_promote<double> { typedef Float type; };
354 #endif // _RHEOLEF_HAVE_FLOAT128
355 
356 // constants in field expressions
357 template <class Value>
359 : std::disjunction<
360  is_rheolef_arithmetic<Value>
361  ,is_point<Value>
362  ,is_tensor<Value>
363  ,is_tensor3<Value>
364  ,is_tensor4<Value>
365  >
366 {};
367 
368 }} // namespace rheolef::details
369 #endif // _RHEOLEF_SPACE_CONSTITUTION_H
field::size_type size_type
Definition: branch.cc:430
see the Float page for the full documentation
see the point page for the full documentation
rheolef::std type
tensor3_basic< Float > tensor3
Definition: tensor3.h:121
size_t size_type
Definition: basis_get.cc:76
tensor_basic< Float > tensor
Definition: tensor.h:181
tensor4_basic< Float > tensor4
Definition: tensor4.h:133
see the tensor3 page for the full documentation
see the tensor4 page for the full documentation
see the tensor page for the full documentation
Expr1::float_type T
Definition: field_expr.h:230
string sys_coord
Definition: mkgeo_grid.sh:171
void check_coord_sys_and_dimension(coordinate_type i, size_type d)
coordinate_type coordinate_system(std::string sys_coord)
std::string coordinate_system_name(coordinate_type i)
valued_type multiplies_result_tag(space_constant::valued_type tag1, space_constant::valued_type tag2)
size_type tensor4_index(valued_type valued, coordinate_type sys_coord, size_type i, size_type j, size_type k, size_type l)
std::string tensor_subscript_name(valued_type valued_tag, coordinate_type sys_coord, size_type i_comp)
size_type tensor_index(valued_type valued_tag, coordinate_type sys_coord, size_type i, size_type j)
valued_type divides_result_tag(space_constant::valued_type tag1, space_constant::valued_type tag2)
std::pair< std::pair< size_type, size_type >, std::pair< size_type, size_type > > tensor4_subscript(valued_type valued, coordinate_type sys_coord, size_type i_comp)
std::string tensor4_subscript_name(valued_type valued, coordinate_type sys_coord, size_type i_comp)
const std::string & valued_name(valued_type valued_tag)
valued_type valued_tag(const std::string &name)
size_type n_component(valued_type valued_tag, size_type d, coordinate_type sys_coord)
std::pair< size_type, size_type > tensor_subscript(valued_type valued_tag, coordinate_type sys_coord, size_type i_comp)
T contract_product(const T &a, const T &b)
This file is part of Rheolef.
rheolef::std enable_if ::type dot const Expr1 expr1, const Expr2 expr2 dot(const Expr1 &expr1, const Expr2 &expr2)
dot(x,y): see the expression page for the full documentation
Definition: vec_expr_v2.h:415
T ddot(const tensor_basic< T > &a, const tensor_basic< T > &b)
ddot(x,y): see the expression page for the full documentation
Definition: tensor.cc:278
#define _RHEOLEF_field_promote_argument(tensor)
T2 operator()(const T1 &x) const
function_traits< F >::result_type type
undeterminated_basic< typename scalar_traits< T >::type > type
undeterminated_basic< typename scalar_traits< T >::type > type
point_basic< typename scalar_traits< T >::type > type
helper for generic field value_type: T, point_basic<T> or tensor_basic<T>