30 #define __Products_H 1
46 template<
typename ExprL,
typename ExprR,
int Type = 1>
51 static const size_type context = ExprL::context | ExprR::context;
52 static const bool is_terminal =
false;
53 static const int product_type = Type;
55 static const uint16_type imorder = ExprL::imorder+ExprR::imorder;
56 static const bool imIsPoly = ExprL::imIsPoly && ExprR::imIsPoly;
58 template<
typename Func>
59 struct HasTestFunction
61 static const bool result =
62 ExprL::template HasTestFunction<Func>::result ||
63 ExprR::template HasTestFunction<Func>::result ;
66 template<
typename Func>
67 struct HasTrialFunction
69 static const bool result =
70 ExprL::template HasTrialFunction<Func>::result||
71 ExprR::template HasTrialFunction<Func>::result ;
79 typedef ExprL left_expression_type;
80 typedef ExprR right_expression_type;
81 typedef typename left_expression_type::value_type value_type;
82 typedef Product<ExprL,ExprR,Type> this_type;
91 explicit Product( left_expression_type
const & left_expr,
92 right_expression_type
const & right_expr )
94 M_left_expr( left_expr ),
95 M_right_expr( right_expr )
97 Product( Product
const & te )
99 M_left_expr( te.M_left_expr ),
100 M_right_expr( te.M_right_expr )
132 left_expression_type
const& left()
const
136 right_expression_type
const& right()
const
143 template<
typename Geo_t,
typename Basis_i_t,
typename Basis_j_t>
146 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
147 typedef typename left_expression_type::template tensor<Geo_t, Basis_i_t, Basis_j_t> l_tensor_expr_type;
148 typedef typename right_expression_type::template tensor<Geo_t, Basis_i_t, Basis_j_t> r_tensor_expr_type;
149 typedef typename l_tensor_expr_type::value_type value_type;
151 typedef typename l_tensor_expr_type::shape left_shape;
152 typedef typename r_tensor_expr_type::shape right_shape;
153 typedef Shape<left_shape::nDim,Scalar,false,false> shape;
154 static const bool l_is_terminal = left_expression_type::is_terminal;
155 static const bool r_is_terminal = right_expression_type::is_terminal;
156 template <
class Args>
struct sig
158 typedef value_type type;
161 BOOST_MPL_ASSERT_MSG( (left_shape::M == right_shape::M) && (left_shape::N == right_shape::N) ,
162 INVALID_RANK_LEFT_AND_RIGHT_SHOULD_BE_THE_SAME,
163 (mpl::int_<left_shape::M>,mpl::int_<right_shape::M>,
164 mpl::int_<left_shape::N>,mpl::int_<right_shape::N>));
168 static const bool value = l_tensor_expr_type::is_zero::value || r_tensor_expr_type::is_zero::value;
171 tensor( this_type
const& expr,
172 Geo_t
const& geom, Basis_i_t
const& fev, Basis_j_t
const& feu )
174 M_l_tensor_expr( expr.left(), geom, fev, feu ),
175 M_r_tensor_expr( expr.right(), geom, fev, feu )
179 tensor( this_type
const& expr,
180 Geo_t
const& geom, Basis_i_t
const& fev )
182 M_l_tensor_expr( expr.left(), geom, fev ),
183 M_r_tensor_expr( expr.right(), geom, fev )
187 tensor( this_type
const& expr, Geo_t
const& geom )
189 M_l_tensor_expr( expr.left(), geom ),
190 M_r_tensor_expr( expr.right(), geom )
194 template<
typename IM>
195 void init( IM
const& im )
197 M_l_tensor_expr.init( im );
198 M_r_tensor_expr.init( im );
200 void update( Geo_t
const& geom, Basis_i_t
const& fev, Basis_j_t
const& feu )
202 M_l_tensor_expr.update( geom, fev, feu );
203 M_r_tensor_expr.update( geom, fev, feu );
205 void update( Geo_t
const& geom, Basis_i_t
const& fev )
207 M_l_tensor_expr.update( geom, fev );
208 M_r_tensor_expr.update( geom, fev );
210 void update( Geo_t
const& geom )
212 M_l_tensor_expr.update( geom );
213 M_r_tensor_expr.update( geom );
215 void update( Geo_t
const& geom, uint16_type face )
217 M_l_tensor_expr.update( geom, face );
218 M_r_tensor_expr.update( geom, face );
222 evalijq( uint16_type i, uint16_type j, uint16_type cc1, uint16_type cc2, uint16_type q )
const
224 return evalijq( i, j, cc1, cc2, q,
typename mpl::and_<mpl::bool_<l_is_terminal>,mpl::bool_<l_is_terminal> >::type() );
227 evalijq( uint16_type i, uint16_type j, uint16_type cc1, uint16_type cc2, uint16_type q, mpl::bool_<0> )
const
233 for (
int c2 = 0; c2 < left_shape::N; ++ c2 )
234 for (
int c1 = 0; c1 < left_shape::M; ++ c1 )
236 res += M_l_tensor_expr.evalijq( i, j, c1, c2, q )*M_r_tensor_expr.evalijq( i, j, c1, c2, q );
243 evalijq( uint16_type i, uint16_type j, uint16_type cc1, uint16_type cc2, uint16_type q, mpl::bool_<1> )
const
247 return ( M_l_tensor_expr.evalijq( i,j,q ).adjoint()*M_r_tensor_expr.evalijq( i,j,q ) ).trace();
251 evaliq( uint16_type i, uint16_type cc1, uint16_type cc2, uint16_type q )
const
257 for (
int c2 = 0; c2 < left_shape::N; ++ c2 )
258 for (
int c1 = 0; c1 < left_shape::M; ++ c1 )
260 res += M_l_tensor_expr.evaliq( i, c1, c2, q )*M_r_tensor_expr.evaliq( i, c1, c2, q );
267 evalq( uint16_type cc1, uint16_type cc2, uint16_type q )
const
273 for (
int c2 = 0; c2 < left_shape::N; ++ c2 )
274 for (
int c1 = 0; c1 < left_shape::M; ++ c1 )
276 res += M_l_tensor_expr.evalq( c1, c2, q )*M_r_tensor_expr.evalq( c1, c2, q );
284 l_tensor_expr_type M_l_tensor_expr;
285 r_tensor_expr_type M_r_tensor_expr;
286 mutable Eigen::Matrix<value_type,left_shape::M,left_shape::N> M1,M2;
290 mutable left_expression_type M_left_expr;
291 mutable right_expression_type M_right_expr;
298 template<
typename ExprL,
typename ExprR>
300 Expr< Product<ExprL, ExprR,1> >
301 inner( ExprL l, ExprR r )
303 typedef Product<ExprL, ExprR,1> product_t;
304 return Expr< product_t >( product_t( l, r ) );
315 template<
typename ExprL,
typename ExprR>
320 static const size_type context = ExprL::context | ExprR::context;
321 static const bool is_terminal =
false;
323 static const uint16_type imorder = ExprL::imorder+ExprR::imorder;
324 static const bool imIsPoly = ExprL::imIsPoly && ExprR::imIsPoly;
326 template<
typename Func>
327 struct HasTestFunction
329 static const bool result =
330 ExprL::template HasTestFunction<Func>::result ||
331 ExprR::template HasTestFunction<Func>::result ;
334 template<
typename Func>
335 struct HasTrialFunction
337 static const bool result =
338 ExprL::template HasTrialFunction<Func>::result||
339 ExprR::template HasTrialFunction<Func>::result ;
347 typedef ExprL left_expression_type;
348 typedef ExprR right_expression_type;
349 typedef typename left_expression_type::value_type value_type;
350 typedef CrossProduct<ExprL,ExprR> this_type;
359 explicit CrossProduct( left_expression_type
const & left_expr,
360 right_expression_type
const & right_expr )
362 M_left_expr( left_expr ),
363 M_right_expr( right_expr )
365 CrossProduct( CrossProduct
const & te )
367 M_left_expr( te.M_left_expr ),
368 M_right_expr( te.M_right_expr )
400 left_expression_type
const& left()
const
404 right_expression_type
const& right()
const
411 template<
typename Geo_t,
typename Basis_i_t,
typename Basis_j_t>
414 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
415 typedef typename left_expression_type::template tensor<Geo_t, Basis_i_t, Basis_j_t> l_tensor_expr_type;
416 typedef typename right_expression_type::template tensor<Geo_t, Basis_i_t, Basis_j_t> r_tensor_expr_type;
417 typedef typename l_tensor_expr_type::value_type value_type;
419 typedef typename l_tensor_expr_type::shape left_shape;
420 typedef typename r_tensor_expr_type::shape right_shape;
421 typedef typename mpl::if_<mpl::equal_to<mpl::int_<left_shape::nDim>,mpl::int_<2> >,
422 mpl::identity<Shape<2,Scalar,false,false> >,
423 mpl::identity<Shape<3,Vectorial,false,false> > >::type::type shape;
424 static const bool l_is_terminal = left_expression_type::is_terminal;
425 static const bool r_is_terminal = right_expression_type::is_terminal;
427 BOOST_MPL_ASSERT_MSG( ( left_shape::nDim > 1 ),
429 (mpl::int_<left_shape::nDim>,mpl::int_<right_shape::nDim>));
430 BOOST_MPL_ASSERT_MSG( left_shape::nDim == right_shape::nDim,
431 INVALID_DIMENSION_LEFT_AND_RIGHT_SHOULD_BE_THE_SAME,
432 (mpl::int_<left_shape::nDim>,mpl::int_<right_shape::nDim>));
433 BOOST_MPL_ASSERT_MSG( (left_shape::M == right_shape::M) && (left_shape::N == right_shape::N) ,
434 INVALID_RANK_LEFT_AND_RIGHT_SHOULD_BE_THE_SAME,
435 (mpl::int_<left_shape::M>,mpl::int_<right_shape::M>,
436 mpl::int_<left_shape::N>,mpl::int_<right_shape::N>));
439 template <
class Args>
struct sig
441 typedef value_type type;
446 static const bool value = l_tensor_expr_type::is_zero::value || r_tensor_expr_type::is_zero::value;
449 tensor( this_type
const& expr,
450 Geo_t
const& geom, Basis_i_t
const& fev, Basis_j_t
const& feu )
452 M_l_tensor_expr( expr.left(), geom, fev, feu ),
453 M_r_tensor_expr( expr.right(), geom, fev, feu )
457 tensor( this_type
const& expr,
458 Geo_t
const& geom, Basis_i_t
const& fev )
460 M_l_tensor_expr( expr.left(), geom, fev ),
461 M_r_tensor_expr( expr.right(), geom, fev )
465 tensor( this_type
const& expr, Geo_t
const& geom )
467 M_l_tensor_expr( expr.left(), geom ),
468 M_r_tensor_expr( expr.right(), geom )
472 template<
typename IM>
473 void init( IM
const& im )
475 M_l_tensor_expr.init( im );
476 M_r_tensor_expr.init( im );
478 void update( Geo_t
const& geom, Basis_i_t
const& fev, Basis_j_t
const& feu )
480 M_l_tensor_expr.update( geom, fev, feu );
481 M_r_tensor_expr.update( geom, fev, feu );
483 void update( Geo_t
const& geom, Basis_i_t
const& fev )
485 M_l_tensor_expr.update( geom, fev );
486 M_r_tensor_expr.update( geom, fev );
488 void update( Geo_t
const& geom )
490 M_l_tensor_expr.update( geom );
491 M_r_tensor_expr.update( geom );
493 void update( Geo_t
const& geom, uint16_type face )
495 M_l_tensor_expr.update( geom, face );
496 M_r_tensor_expr.update( geom, face );
500 evalijq( uint16_type i, uint16_type j, uint16_type cc1, uint16_type cc2, uint16_type q )
const
502 return evalijq( i, j, cc1, cc2, q, mpl::int_<left_shape::nDim>() );
505 evalijq( uint16_type i, uint16_type j, uint16_type cc1, uint16_type cc2, uint16_type q, mpl::int_<2> )
const
507 double res = M_l_tensor_expr.evalijq( i, j, 0, 0, q )*M_r_tensor_expr.evalijq( i, j, 1, 0, q );
508 res -= M_l_tensor_expr.evalijq( i, j, 1, 0, q )*M_r_tensor_expr.evalijq( i, j, 0, 0, q );
512 evalijq( uint16_type i, uint16_type j, uint16_type cc1, uint16_type cc2, uint16_type q, mpl::int_<3> )
const
514 double res = M_l_tensor_expr.evalijq( i, j, (cc1+1)%3, 0, q )*M_r_tensor_expr.evalijq( i, j, (cc1+2)%3, 0, q );
515 res -= M_l_tensor_expr.evalijq( i, j, (cc1+2)%3, 0, q )*M_r_tensor_expr.evalijq( i, j, (cc1+1)%3, 0, q );
519 evaliq( uint16_type i, uint16_type cc1, uint16_type cc2, uint16_type q )
const
521 return evaliq( i, cc1, cc2, q, mpl::int_<left_shape::nDim>() );
524 evaliq( uint16_type i, uint16_type cc1, uint16_type cc2, uint16_type q, mpl::int_<2> )
const
526 double res = M_l_tensor_expr.evaliq( i, 0, 0, q )*M_r_tensor_expr.evaliq( i, 1, 0, q );
527 res -= M_l_tensor_expr.evaliq( i, 1, 0, q )*M_r_tensor_expr.evaliq( i, 0, 0, q );
531 evaliq( uint16_type i, uint16_type cc1, uint16_type cc2, uint16_type q, mpl::int_<3> )
const
533 double res = M_l_tensor_expr.evaliq( i, (cc1+1)%3, 0, q )*M_r_tensor_expr.evaliq( i, (cc1+2)%3, 0, q );
534 res -= M_l_tensor_expr.evaliq( i, (cc1+2)%3, 0, q )*M_r_tensor_expr.evaliq( i, (cc1+1)%3, 0, q );
538 evalq( uint16_type cc1, uint16_type cc2, uint16_type q )
const
540 return evalq( cc1, cc2, q, mpl::int_<left_shape::nDim>() );
543 evalq( uint16_type cc1, uint16_type cc2, uint16_type q, mpl::int_<2> )
const
545 double res = M_l_tensor_expr.evalq( 0, 0, q )*M_r_tensor_expr.evalq( 1, 0, q );
546 res -= M_l_tensor_expr.evalq( 1, 0, q )*M_r_tensor_expr.evalq( 0, 0, q );
550 evalq( uint16_type cc1, uint16_type cc2, uint16_type q, mpl::int_<3> )
const
552 double res = M_l_tensor_expr.evalq( (cc1+1)%3, 0, q )*M_r_tensor_expr.evalq( (cc1+2)%3, 0, q );
553 res -= M_l_tensor_expr.evalq( (cc1+2)%3, 0, q )*M_r_tensor_expr.evalq( (cc1+1)%3, 0, q );
558 l_tensor_expr_type M_l_tensor_expr;
559 r_tensor_expr_type M_r_tensor_expr;
563 mutable left_expression_type M_left_expr;
564 mutable right_expression_type M_right_expr;
571 template<
typename ExprL,
typename ExprR>
573 Expr< CrossProduct<ExprL, ExprR> >
574 cross( ExprL l, ExprR r )
576 typedef CrossProduct<ExprL, ExprR> product_t;
577 return Expr< product_t >( product_t( l, r ) );
size_t size_type
Indices (starting from 0)
Definition: feelcore/feel.hpp:319