Rheolef  7.1
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 {
34 
35 namespace details {
36 
37 // is_equal : used by type resolution and by is_symmetric
38 template <class T1, class T2> struct is_equal : std::false_type {};
39 template <class T> struct is_equal<T,T> : std::true_type {};
40 
41 // switch for a constant, or a pointer-to-function or a class-function:
42 template<class T> struct is_scalar : std::false_type {};
43 template<> struct is_scalar<int> : std::true_type {};
44 template<> struct is_scalar<const int> : std::true_type {};
45 template<> struct is_scalar<size_t> : std::true_type {};
46 template<> struct is_scalar<double> : std::true_type {};
47 #ifdef _RHEOLEF_HAVE_FLOAT128
48 template<> struct is_scalar<float128> : std::true_type {};
49 #endif // _RHEOLEF_HAVE_FLOAT128
50 
51 template<class T> struct is_point : std::false_type {};
52 template<class T> struct is_point<point_basic<T> > : std::true_type {};
53 
54 template<class T> struct is_tensor : std::false_type {};
55 template<class T> struct is_tensor<tensor_basic<T> > : std::true_type {};
56 
57 template<class T> struct is_tensor3 : std::false_type {};
58 template<class T> struct is_tensor3<tensor3_basic<T> > : std::true_type {};
59 
60 template<class T> struct is_tensor4 : std::false_type {};
61 template<class T> struct is_tensor4<tensor4_basic<T> > : std::true_type {};
62 
63 } // namespace details
64 // ---------------------------------------------------------------------------
65 // argument promote, for template expression (binders, etc)
66 // ---------------------------------------------------------------------------
67 namespace details {
68 template <class T1, class T2, class Sfinae = void>
70 template <class T1, class T2, class Sfinae = void>
72 
73 #define _RHEOLEF_field_promote_argument(tensor) \
74 template<class T1, class T2> \
75 struct field_promote_first_argument<tensor##_basic<T1>, T2, \
76  typename std::enable_if< \
77  is_rheolef_arithmetic<T1>::value \
78  && is_rheolef_arithmetic<T2>::value \
79  >::type \
80 > { \
81  using type = tensor##_basic<typename promote<T1,T2>::type>; }; \
82 template <class T1, class T2> \
83 struct field_promote_first_argument<T1,tensor##_basic<T2>, \
84  typename std::enable_if< \
85  is_rheolef_arithmetic<T1>::value \
86  && is_rheolef_arithmetic<T2>::value \
87  >::type \
88 > { \
89  using type = typename promote<T1,T2>::type; }; \
90 template <class T1, class T2> \
91 struct field_promote_second_argument<tensor##_basic<T1>, T2, \
92  typename std::enable_if< \
93  is_rheolef_arithmetic<T1>::value \
94  && is_rheolef_arithmetic<T2>::value \
95  >::type \
96 > { \
97  using type = typename promote<T1,T2>::type; }; \
98 template <class T1, class T2> \
99 struct field_promote_second_argument<T1,tensor##_basic<T2>, \
100  typename std::enable_if< \
101  is_rheolef_arithmetic<T1>::value \
102  && is_rheolef_arithmetic<T2>::value \
103  >::type \
104 > { \
105  using type = tensor##_basic<typename promote<T1,T2>::type>; };
106 
111 #undef _RHEOLEF_field_promote_argument
112 
113 } // namespace details
114 // -------------------------------------------------------------
115 // coordinate system helper
116 // -------------------------------------------------------------
117 namespace space_constant {
118 
119 typedef size_t size_type;
120 
121 typedef enum {
125  last_coord_sys = 3
127 
131 
132 // -------------------------------------------------------------
133 // multi-component field support
134 // -------------------------------------------------------------
135 typedef enum {
136  scalar = 0,
137  vector = 1,
138  tensor = 2, // symmetric, D_ij
140  tensor3 = 4, // unsymmetric, G_ijk
141  tensor4 = 5, // symmetric, A_ijkl
142  mixed = 6,
143  last_valued = 7
145 
146 const std::string& valued_name (valued_type tag);
147 valued_type valued_tag (const std::string& name);
148 
151  size_type d,
153 
155  const std::string& valued,
156  size_type d,
158 
159 // convert a type to the enum valued_tag:
160 // size_t tag = valued_tag_traits<T>::value;
161 template<class T> struct valued_tag_traits { static const valued_type value = scalar; };
162 template<class T> struct valued_tag_traits<point_basic<T> > { static const valued_type value = vector; };
163 template<class T> struct valued_tag_traits<tensor_basic<T> > { static const valued_type value = tensor; };
164 template<class T> struct valued_tag_traits<tensor3_basic<T> > { static const valued_type value = tensor3; };
165 template<class T> struct valued_tag_traits<tensor4_basic<T> > { static const valued_type value = tensor4; };
166 template<class T> struct valued_tag_traits<undeterminated_basic<T> > { static const valued_type value = last_valued; };
167 
168 // convert an enum valued_tag to the type based on T:
169 // typedef typename valued_type_traits<tag,T>::type valued_t;
170 //
171 template<int Tag, class T> struct valued_type_traits { typedef undeterminated_basic<T> type; };
172 template<class T> struct valued_type_traits<scalar,T> { typedef T type; };
173 template<class T> struct valued_type_traits<vector,T> { typedef point_basic<T> type; };
174 template<class T> struct valued_type_traits<tensor,T> { typedef tensor_basic<T> type; };
175 template<class T> struct valued_type_traits<tensor3,T> { typedef tensor3_basic<T> type; };
176 template<class T> struct valued_type_traits<tensor4,T> { typedef tensor4_basic<T> type; };
177 template<class T> struct valued_type_traits<last_valued,T> { typedef undeterminated_basic<T> type; };
178 
179 // tensorial up and down helpers (for grad(expr))
181 template<class T> struct rank_down<point_basic<T> > { typedef T type; };
182 template<class T> struct rank_down<tensor_basic<T> > { typedef point_basic<T> type; };
183 template<class T> struct rank_down<tensor3_basic<T> > { typedef tensor_basic<T> type; };
184 template<class T> struct rank_down<tensor4_basic<T> > { typedef tensor3_basic<T> type; };
185 
186 template<class T> struct rank_up { typedef point_basic<typename scalar_traits<T>::type> type; };
187 template<class T> struct rank_up<point_basic<T> > { typedef tensor_basic<T> type; };
188 template<class T> struct rank_up<tensor_basic<T> > { typedef tensor3_basic<T> type; };
189 template<class T> struct rank_up<tensor3_basic<T> > { typedef tensor4_basic<T> type; };
191 
192 template<class T>
193 T contract_product (const T& a, const T& b) { return a*b; }
194 template<class T>
195 T contract_product (const point_basic<T>& a, const point_basic<T>& b) { return dot(a,b); }
196 template<class T>
197 T contract_product (const tensor_basic<T>& a, const tensor_basic<T>& b) { return ddot(a,b); }
198 
199 // -------------------------------------------------------------
200 // 2-tensor support
201 // -------------------------------------------------------------
205  size_type i,
206  size_type j);
207 
209  std::string valued,
210  std::string sys_coord,
211  size_type i,
212  size_type j);
213 
214 std::pair<size_type,size_type>
218  size_type i_comp);
219 
220 std::string
224  size_type i_comp);
225 
226 std::pair<size_type,size_type>
228  std::string valued,
229  std::string sys_coord,
230  size_type i_comp);
231 
232 std::string
234  std::string valued,
235  std::string sys_coord,
236  size_type i_comp);
237 
238 // -------------------------------------------------------------
239 // 4-tensor support
240 // -------------------------------------------------------------
241 size_type
243  valued_type valued,
245  size_type i,
246  size_type j,
247  size_type k,
248  size_type l);
249 
250 size_type
252  std::string valued,
253  std::string sys_coord,
254  size_type i,
255  size_type j,
256  size_type k,
257  size_type l);
258 
259 std::pair<std::pair<size_type,size_type>, std::pair<size_type,size_type> >
261  valued_type valued,
263  size_type i_comp);
264 
265 std::string
267  valued_type valued,
269  size_type i_comp);
270 
271 std::pair<std::pair<size_type,size_type>, std::pair<size_type,size_type> >
273  std::string valued,
274  std::string sys_coord,
275  size_type i_comp);
276 
277 std::string
279  std::string valued,
280  std::string sys_coord,
281  size_type i_comp);
282 
283 // -------------------------------------------------------------
284 // field*field & field/field valued_type computed at run time
285 // -------------------------------------------------------------
288 
289 
290 } // namespace space_constant
291 // --------------------------------------------------------------------------
292 // utility to determine whether a template arg is a function or a constant
293 // --------------------------------------------------------------------------
294 namespace details {
295  // build a function that returns a constant
296  template<class T1, class T2>
297  struct f_constant {
298  T2 operator() (const T1& x) const { return c; }
299  f_constant (const T2& c0) : c(c0) {}
300  const T2 c;
301  };
302  template<class F> struct is_vector_function :
303  and_type <
304  std::is_class<F>
305  ,is_point<typename F::result_type>
306  > {};
307  template<class T> struct is_vector_function<point_basic<T> (const point_basic<T>)>
308  : std::true_type {};
309 
310  template<class E> class field_nonlinear_expr;
311  template<class E> struct is_expr : std::false_type {};
312  template<class E> struct is_expr<field_nonlinear_expr<E> > : std::true_type {};
313 
314  template<class C>
315  struct is_constant :
316  or_type <
317  is_scalar<C>
318  ,is_point<C>
319  > {};
320 
321  template<class F>
322  struct is_function :
323  and_type <
324  or_type <
325  std::is_class<F>
326  ,std::is_pointer<F>
327  ,std::is_function<F>
328  >
329  ,not_type <
330  or_type <
331  is_scalar<F>
332  ,is_point<F>
333  ,is_expr<F>
334  >
335  >
336  >
337  {};
338  template<class F>
339  struct result_type {
341  };
342  template<class T, class R>
343  struct result_type<R(const point_basic<T>&)> {
344  typedef R type;
345  };
346  template<class T, class R>
347  struct result_type<R (*)(const point_basic<T>&)> {
348  typedef R type;
349  };
350  template<class Constant>
351  struct constant_promote { typedef Constant type; };
352  template<> struct constant_promote<int> { typedef Float type; };
353  template<> struct constant_promote<size_t> { typedef Float type; };
354 #ifdef _RHEOLEF_HAVE_FLOAT128
355  template<> struct constant_promote<double> { typedef Float type; };
356 #endif // _RHEOLEF_HAVE_FLOAT128
357 } // namespace details
358 } // namespace rheolef
359 #endif // _RHEOLEF_SPACE_CONSTITUTION_H
field::size_type size_type
Definition: branch.cc:425
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:261
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>