Logo  0.95.0-final
Finite Element Embedded Library and Language in C++
Feel++ Feel++ on Github Feel++ community
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
shape.hpp
Go to the documentation of this file.
1 /* -*- mode: c++; coding: utf-8; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; show-trailing-whitespace: t -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4
2 
3  This file is part of the Feel library
4 
5  Author(s): Christophe Prud'homme <christophe.prudhomme@feelpp.org>
6  Date: 2006-11-13
7 
8  Copyright (C) 2006,2007 Universite Joseph Fourier (Grenoble I)
9  Copyright (C) 2012 Universite de Strasbourg
10 
11  This library is free software; you can redistribute it and/or
12  modify it under the terms of the GNU Lesser General Public
13  License as published by the Free Software Foundation; either
14  version 3.0 of the License, or (at your option) any later version.
15 
16  This library is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  Lesser General Public License for more details.
20 
21  You should have received a copy of the GNU Lesser General Public
22  License along with this library; if not, write to the Free Software
23  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 */
30 #ifndef __Shape_H
31 #define __Shape_H 1
32 
33 #include <boost/numeric/ublas/storage.hpp>
34 
35 namespace Feel
36 {
37 namespace vf
38 {
40 
47 template<uint16_type Dim, template<uint16_type D> class Type, bool is_transposed, bool diag = false>
48 class Shape
49 {
50 };
51 
59 template<uint16_type Dim, bool transpose, bool diag>
60 class Shape<Dim,Scalar,transpose,diag>
61 {
62 public:
63 
67 
68  static const uint16_type nDim = Dim;
69  static const uint16_type M = 1;
70  static const uint16_type N = 1;
71  static const uint16_type O = 1;
72  static const bool is_transposed = transpose;
73  static const bool is_diagonalized = diag;
74  static const uint16_type rank = Scalar<nDim>::rank;
75 
76  static const bool is_scalar = Scalar<nDim>::is_scalar;
77  static const bool is_vectorial = Scalar<nDim>::is_vectorial;
78  static const bool is_tensor2 = Scalar<nDim>::is_tensor2;
79  static const bool is_tensor3 = Scalar<nDim>::is_tensor3;
81 
85 
86  typedef Shape<Dim,Scalar,transpose, is_diagonalized> shape_type;
87 
89 };
90 
98 template<uint16_type Dim, bool transpose, bool diag>
99 class Shape<Dim,Vectorial,transpose, diag>
100 {
101 public:
102 
106 
107  static const uint16_type nDim = Dim;
108  static const uint16_type M = mpl::if_<mpl::equal_to<mpl::bool_<transpose>, mpl::bool_<true> >,
109  mpl::int_<1>, mpl::int_<nDim> >::type::value;
110  static const uint16_type N = mpl::if_<mpl::equal_to<mpl::bool_<transpose>, mpl::bool_<true> >, mpl::int_<nDim>, mpl::int_<1> >::type::value;
111  static const uint16_type O = 1;
112  static const bool is_transposed = transpose;
113  static const bool is_diagonalized = diag;
114  static const uint16_type rank = Vectorial<nDim>::rank;
115 
116  static const bool is_scalar = Vectorial<nDim>::is_scalar;
117  static const bool is_vectorial = Vectorial<nDim>::is_vectorial;
118  static const bool is_tensor2 = Vectorial<nDim>::is_tensor2;
119  static const bool is_tensor3 = Vectorial<nDim>::is_tensor3;
121 
125 
126  typedef Shape<Dim,Vectorial,transpose, is_diagonalized> shape_type;
128 };
129 
137 template<uint16_type Dim, bool transpose, bool diag>
138 class Shape<Dim,Tensor2,transpose,diag>
139 {
140 public:
141 
145 
146  static const uint16_type nDim = Dim;
147  static const uint16_type M = nDim;
148  static const uint16_type N = nDim;
149  static const uint16_type O = 1;
150  static const bool is_transposed = transpose;
151  static const bool is_diagonalized = diag;
152  static const uint16_type rank = Tensor2<nDim>::rank;
153 
154  static const bool is_scalar = Tensor2<nDim>::is_scalar;
155  static const bool is_vectorial = Tensor2<nDim>::is_vectorial;
156  static const bool is_tensor2 = Tensor2<nDim>::is_tensor2;
157  static const bool is_tensor3 = Tensor2<nDim>::is_tensor3;
159 
163 
164  typedef Shape<Dim,Tensor2,transpose,diag> shape_type;
166 };
167 
175 template<uint16_type Dim, bool transpose, bool diag>
176 class Shape<Dim,Tensor3,transpose,diag>
177 {
178 public:
179 
183 
184  static const uint16_type nDim = Dim;
185  static const uint16_type M = nDim;
186  static const uint16_type N = nDim;
187  static const uint16_type O = nDim;
188  static const bool is_transposed = transpose;
189  static const bool is_diagonalized = diag;
190  static const uint16_type rank = Tensor3<nDim>::rank;
191 
192  static const bool is_scalar = Tensor3<nDim>::is_scalar;
193  static const bool is_vectorial = Tensor3<nDim>::is_vectorial;
194  static const bool is_tensor2 = Tensor3<nDim>::is_tensor2;
195  static const bool is_tensor3 = Tensor3<nDim>::is_tensor3;
197 
201 
202  typedef Shape<Dim,Tensor3,transpose,diag> shape_type;
204 };
205 
206 //template<uint16_type Dim, template<uint16_type D> class Type, bool transpose>
207 template<typename TheShape>
208 class Transpose
209 {
210 public:
214  //typedef Shape<Dim,Type,transpose> original_shape_type;
215  typedef TheShape original_shape_type;
216 
217  typedef typename mpl::if_<mpl::bool_<original_shape_type::is_scalar>,
218  mpl::identity<Shape<original_shape_type::nDim,Scalar,!original_shape_type::is_transposed,original_shape_type::is_diagonalized> >,
219  typename mpl::if_<mpl::bool_<original_shape_type::is_vectorial>,
220  mpl::identity<Shape<original_shape_type::nDim,Vectorial,!original_shape_type::is_transposed,original_shape_type::is_diagonalized> >,
221  typename mpl::if_<mpl::bool_<original_shape_type::is_tensor2>,
222  mpl::identity<Shape<original_shape_type::nDim,Tensor2,!original_shape_type::is_transposed,original_shape_type::is_diagonalized> >,
223  mpl::identity<Shape<original_shape_type::nDim,Tensor3,!original_shape_type::is_transposed,original_shape_type::is_diagonalized> >
224  >::type >::type >::type::type type;
225 
227 };
228 
229 //template<uint16_type Dim, template<uint16_type D> class Type, bool transpose>
230 template<typename TheShape>
231 class Diag
232 {
233 public:
237  //typedef Shape<Dim,Type,transpose> original_shape_type;
238  typedef TheShape original_shape_type;
239 
240  typedef typename mpl::if_<mpl::bool_<original_shape_type::is_scalar>,
241  mpl::identity<Shape<original_shape_type::nDim,Scalar,original_shape_type::is_transposed,original_shape_type::is_diagonalized> >,
242  typename mpl::if_<mpl::bool_<original_shape_type::is_vectorial>,
243  mpl::identity<Shape<original_shape_type::nDim,Tensor2,original_shape_type::is_transposed,original_shape_type::is_diagonalized> >,
244  mpl::identity<Shape<original_shape_type::nDim,Vectorial,original_shape_type::is_transposed,original_shape_type::is_diagonalized> >
245  >::type >::type::type type;
246 
248 };
249 
250 
251 template<typename Left, typename Right>
252 struct shape_op_samerank
253 {
254  static const bool is_rank_ok = ( ( Left::M == Right::M ) && ( Left::N == Right::N ) );
255  BOOST_MPL_ASSERT_MSG( mpl::bool_<is_rank_ok>::value,
256  INVALID_TENSOR_OPERATION_SHOULD_BE_OF_SAME_RANK,
257  ( mpl::int_<Left::M>, mpl::int_<Left::N>,
258  mpl::int_<Right::M>, mpl::int_<Right::N>,
259  Left, Right ) );
260 
261 
262  static const uint16_type nDim = Left::nDim;
263  static const bool is_diagonalized = Left::is_diagonalized && Right::is_diagonalized;
264  static const bool is_transposed = Left::is_transposed && Right::is_transposed;
265 
266  typedef typename mpl::if_<mpl::bool_<Left::is_scalar>,
267  mpl::identity<Shape<nDim,Scalar,is_transposed,is_diagonalized> >,
268  typename mpl::if_<mpl::bool_<Left::is_vectorial>,
269  mpl::identity<Shape<nDim,Vectorial,is_transposed,is_diagonalized> >,
270  typename mpl::if_<mpl::bool_<Left::is_tensor2>,
271  mpl::identity<Shape<nDim,Tensor2,is_transposed,is_diagonalized> >,
272  mpl::identity<Shape<nDim,Tensor3,is_transposed,is_diagonalized> >
273  >::type >::type >::type::type type;
274 
275  static const int op = 0;
276 
277  template<bool left_is_zero, bool right_is_zero>
278  struct is_zero
279  {
280  static const bool value = ( left_is_zero && right_is_zero );
281  static const bool update_and_eval_left = !left_is_zero;
282  static const bool update_and_eval_right = !right_is_zero;
283  };
284 };
285 
286 template<typename Left, typename Right>
287 struct shape_op_id
288 {
289  static const uint16_type nDim = Left::nDim;
290  static const bool is_diagonalized = Left::is_diagonalized && Right::is_diagonalized;
291  static const bool is_transposed = Left::is_transposed && Right::is_transposed;
292 
293  typedef typename mpl::if_<mpl::bool_<Left::is_scalar>,
294  mpl::identity<Shape<nDim,Scalar,is_transposed,is_diagonalized> >,
295  typename mpl::if_<mpl::bool_<Left::is_vectorial>,
296  mpl::identity<Shape<nDim,Vectorial,is_transposed,is_diagonalized> >,
297  typename mpl::if_<mpl::bool_<Left::is_tensor2>,
298  mpl::identity<Shape<nDim,Tensor2,is_transposed,is_diagonalized> >,
299  mpl::identity<Shape<nDim,Tensor3,is_transposed,is_diagonalized> >
300  >::type >::type >::type::type type;
301 
302  static const int op = 0;
303 
304  template<bool left_is_zero, bool right_is_zero>
305  struct is_zero
306  {
307  static const bool value = ( left_is_zero||right_is_zero );
308  static const bool update_and_eval_left = !value;
309  static const bool update_and_eval_right = !value;
310  };
311 };
312 
313 struct INVALID_MULTIPLICATION {};
314 template<int D, uint16_type M, uint16_type N>
315 struct mn_to_shape
316 {
317  typedef typename mpl::if_<mpl::greater<mpl::int_<M>,
318  mpl::int_<N> >,
319  mpl::identity<Shape<D, Vectorial, false, false> >,
320  typename mpl::if_<mpl::greater<mpl::int_<N>,
321  mpl::int_<M> >,
322  mpl::identity<Shape<D, Vectorial, true, false> >,
323  typename mpl::if_<mpl::equal_to<mpl::int_<N>,
324  mpl::int_<1> >,
325  mpl::identity<Shape<D, Scalar, false,false> >,
326  mpl::identity<Shape<D, Tensor2, false,false> > >::type>::type>::type::type type;
327 
328 
329 };
330 
331 template<typename Left, typename Right>
332 struct shape_op_mul
333 {
334 
335  typedef typename mpl::if_<mpl::bool_<Left::is_scalar>,
336  mpl::identity<Right>,
337  typename mpl::if_<mpl::bool_<Right::is_scalar>,
338  mpl::identity<Left>,
339 
340  // check that Left::N == Right::M
341  typename mpl::if_<mpl::equal_to<mpl::int_<Left::N>,
342  mpl::int_<Right::M> >,
343  mpl::identity<typename mn_to_shape<Left::nDim,
344  Left::M,
345  Right::N >::type >,
346  mpl::identity<typename shape_op_id<Left, Right>::type> >::type >::type>::type::type type;
347 
348  static const int op = mpl::if_<mpl::or_<mpl::bool_<Left::is_scalar>,
349  mpl::bool_<Right::is_scalar> >,
350  mpl::int_<0>,
351  mpl::int_<1> >::type::value;
352  template<bool left_is_zero, bool right_is_zero>
353  struct is_zero
354  {
355  static const bool value = ( left_is_zero||right_is_zero );
356  static const bool update_and_eval_left = !value;
357  static const bool update_and_eval_right = !value;
358  };
359 };
360 
361 
362 template<typename Left, typename Right>
363 struct shape_op_div
364 {
365 
366  BOOST_MPL_ASSERT_MSG( mpl::bool_<Right::is_scalar>::value,
367  INVALID_TENSOR_RANK_FOR_DIVISION_SHOULD_BE_0,
368  ( Left, Right ) );
369 
370  typedef typename mpl::if_<mpl::bool_<Right::is_scalar>,
371  mpl::identity<mpl::identity<Left> >,
372  mpl::identity<shape_op_id<Left, Right> > >::type::type::type type;
373 
374  static const int op = 0;
375 
376  template<bool left_is_zero, bool right_is_zero>
377  struct is_zero
378  {
379  //BOOST_MPL_ASSERT_MSG( (!right_is_zero), (INVALID_OPERATION_DIV_BY_ZERO), (left_is_zero,right_is_zero));
380  static const bool value = left_is_zero;
381  static const bool update_and_eval_left = !value;
382  static const bool update_and_eval_right = !value;
383  };
384 };
385 
386 template<uint16_type Dim, template<uint16_type D> class Type, bool is_transposed, bool diag>
387 std::ostream& operator<<( std::ostream& os, Shape<Dim, Type, is_transposed, diag> const& shape )
388 {
389  os << "shape = [ndim = " << shape.nDim << ", rank = " << shape.rank << ", M = " << shape.M << ", N = " << shape.N << "]";
390 
391  return os;
392 }
394 } // vf
395 } // Feel
396 #endif /* __Shape_H */

Generated on Sun Oct 20 2013 08:25:04 for Feel++ by doxygen 1.8.4