36 #ifndef NEKTAR_LIB_UTILITIES_NEK_VECTOR_HPP
37 #define NEKTAR_LIB_UTILITIES_NEK_VECTOR_HPP
39 #include <ExpressionTemplates/ExpressionTemplates.hpp>
59 #include <boost/call_traits.hpp>
60 #include <boost/type_traits.hpp>
61 #include <boost/shared_array.hpp>
62 #include <boost/typeof/typeof.hpp>
64 #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
68 template<
typename DataType>
85 typename boost::call_traits<DataType>::const_reference
y,
86 typename boost::call_traits<DataType>::const_reference
z);
96 #ifdef NEKTAR_USE_EXPRESSION_TEMPLATES
97 template<
typename L,
typename Op,
typename R>
98 NekVector(
const expt::Node<L, Op, R>& rhs) :
99 m_size(MatrixSize<expt::Node<L, Op, R>,
typename expt::Node<L, Op, R>::Indices, 0>::
template GetRequiredSize(rhs.GetData()).
template get<0>()),
103 expt::ExpressionEvaluator::EvaluateWithoutAliasingCheck(rhs, *
this);
106 template<
typename L,
typename Op,
typename R>
109 boost::tuple<unsigned int, unsigned int, unsigned int> sizes =
110 MatrixSize<expt::Node<L, Op, R>,
typename expt::Node<L, Op, R>::Indices, 0>::GetRequiredSize(rhs.GetData());
111 unsigned int newRows = sizes.get<0>();
116 if( this->
GetData().num_elements() < newRows )
124 "Attempting to store too many elements in a wrapped vector.");
127 expt::ExpressionEvaluator::Evaluate(rhs, *
this);
130 #endif //NEKTAR_USE_EXPRESSION_TEMPLATES
203 #ifdef NEKTAR_USE_EXPRESSION_TEMPLATES
204 expt::Node<expt::Node<NekVector<DataType> >, expt::NegateOp,
void >
operator-()
const
206 expt::Node<NekVector<DataType> > leafNode(*
this);
207 return expt::Node<expt::Node<NekVector<DataType> >, expt::NegateOp,
void >(leafNode);
247 template<
typename DataType>
252 template<
typename DataType>
257 template<
typename DataType>
261 template<
typename DataType>
272 template<
typename ResultDataType,
typename InputDataType>
277 template<
typename ResultDataType,
typename InputDataType>
282 template<
typename ResultDataType,
typename InputDataType>
286 template<
typename ResultDataType,
typename InputDataType>
290 template<
typename DataType>
299 template<
typename ResultDataType,
typename InputDataType>
304 template<
typename ResultDataType>
308 template<
typename DataType>
314 template<
typename ResultDataType,
typename InputDataType>
319 template<
typename ResultDataType,
typename InputDataType>
323 template<
typename DataType,
typename InputDataType>
328 template<
typename ResultDataType,
typename InputDataType>
333 template<
typename ResultDataType>
337 template<
typename DataType>
342 template<
typename ResultDataType,
typename InputDataType>
347 template<
typename ResultDataType,
typename InputDataType>
352 template<
typename DataType>
366 template<
typename DataType>
367 LIB_UTILITIES_EXPORT std::ostream& operator<<(std::ostream& os, const NekVector<DataType>& rhs);
369 template<
typename DataType>
372 template<
typename DataType>
375 template<
typename DataType>
378 template<
typename DataType>
381 template<
typename DataType>
384 template<
typename DataType>
388 template<
typename DataType>
392 template<
typename DataType>
395 template<
typename DataType>
398 template<
typename DataType>
401 template<
typename DataType>
404 template<
typename DataType>
410 template<
typename DataType>
413 template<
typename DataType>
416 template<
typename DataType>
421 #ifdef NEKTAR_USE_EXPRESSION_TEMPLATES
424 template<
typename DataType,
typename L,
typename Op,
typename R>
426 const expt::Node<L, Op, R>& expr)
430 typename expt::Node<L, Op, R>::ResultType rhs = expt::ExpressionEvaluator::Evaluate(expr);
431 return Dot(lhs, rhs);
434 template<
typename DataType>
443 template<
typename DataType,
typename NodeType,
typename Indices,
unsigned int StartIndex>
444 struct CreateFromTree<Nektar::NekVector<DataType>, NodeType, Indices, StartIndex>
446 template<
typename ArgVectorType>
449 boost::tuple<unsigned int, unsigned int, unsigned int> sizes =
450 Nektar::MatrixSize<NodeType, Indices, StartIndex>::GetRequiredSize(tree);
452 unsigned int rows = sizes.get<0>();
460 template<
typename NodeType,
typename enabled =
void>
461 struct NodeCanUnroll :
public boost::false_type {};
463 template<
typename Type>
464 struct NodeCanUnroll<expt::Node<Type, void, void>,
465 typename boost::enable_if
467 Nektar::IsVector<typename expt::Node<Type, void, void>::ResultType>
468 >::type > :
public boost::true_type
472 template<
typename LhsType,
typename OpType,
typename RhsType>
473 struct NodeCanUnroll<expt::Node<LhsType, OpType, RhsType>,
474 typename boost::enable_if
478 Nektar::IsVector<typename LhsType::ResultType>,
479 Nektar::IsVector<typename RhsType::ResultType>,
480 NodeCanUnroll<LhsType>,
481 NodeCanUnroll<RhsType>,
484 boost::is_same<OpType, expt::AddOp>
487 > >::type >:
public boost::true_type
491 template<
typename NodeType,
typename IndicesType,
unsigned int index>
494 template<
typename LhsType,
typename IndicesType,
unsigned int index>
495 struct Accumulate<expt::Node<LhsType, void, void>, IndicesType, index>
497 static const unsigned int MappedIndex = boost::mpl::at_c<IndicesType, index>::type::value;
499 template<
typename ResultType,
typename ArgumentVectorType>
500 static void Execute(ResultType& accumulator,
const ArgumentVectorType& args,
unsigned int i)
502 accumulator = boost::fusion::at_c<MappedIndex>(args)[i];
506 template<
typename LhsType,
typename Op,
typename RhsType,
typename IndicesType,
unsigned int index>
507 struct Accumulate<expt::Node<LhsType, Op, RhsType>, IndicesType, index>
509 static const int rhsNodeIndex = index + LhsType::TotalCount;
511 template<
typename ResultType,
typename ArgumentVectorType>
512 static void Execute(ResultType& accumulator,
const ArgumentVectorType& args,
unsigned int i)
514 Accumulate<LhsType, IndicesType, index>::Execute(accumulator, args, i);
516 Accumulate<RhsType, IndicesType, rhsNodeIndex>::Execute(rhs, args, i);
517 Op::OpEqual(accumulator, rhs);
523 template<
typename IndicesType,
unsigned int startIndex,
unsigned int endIndex,
typename enabled=
void>
526 #ifndef NEKTAR_NEKVECTOR_MAX_UNROLL_ARGS
527 #define NEKTAR_NEKVECTOR_MAX_UNROLL_ARGS 10
530 #define NEKTAR_NEKVECTOR_UNROLL_GENERATE_INDEX(z, n, IndexName) \
531 static const unsigned int BOOST_PP_CAT(IndexName, n) = boost::mpl::at_c<IndicesType, startIndex+n>::type::value;
533 #define NEKTAR_NEKVECTOR_UNROLL_GENERATE_VARIABLE(z, n, VariableName) \
534 BOOST_AUTO(BOOST_PP_CAT(VariableName, n), boost::fusion::at_c<BOOST_PP_CAT(index, n)>(args).GetRawPtr());
536 #define NEKTAR_NEKVECTOR_UNROLL_GENERATE_VARIABLE_NAME_IN_ADDITION_SEQUENCE(z, n, VariableName) \
537 + BOOST_PP_CAT(VariableName, n)[i]
539 #define NEKTAR_NEKVECTOR_UNROLL_IMPL(z, n, ClassName) \
540 template<typename IndicesType, unsigned int startIndex, unsigned int endIndex> \
541 struct ClassName<IndicesType, startIndex, endIndex, \
542 typename boost::enable_if_c \
544 endIndex-startIndex == BOOST_PP_CAT(n, u) \
547 BOOST_PP_REPEAT_FROM_TO(0, n, NEKTAR_NEKVECTOR_UNROLL_GENERATE_INDEX, index)\
549 template<typename AccumulatorType, typename ArgumentVectorType> \
550 static inline void Execute(AccumulatorType& accumulator, const ArgumentVectorType& args) \
552 BOOST_AUTO(a, accumulator.GetRawPtr()); \
553 BOOST_PP_REPEAT_FROM_TO(0, n, NEKTAR_NEKVECTOR_UNROLL_GENERATE_VARIABLE, t) \
555 const unsigned int r = accumulator.GetRows(); \
556 for(unsigned int i = 0; i < r; ++i) \
559 BOOST_PP_REPEAT_FROM_TO(1, n, NEKTAR_NEKVECTOR_UNROLL_GENERATE_VARIABLE_NAME_IN_ADDITION_SEQUENCE, t); \
564 BOOST_PP_REPEAT_FROM_TO(2, NEKTAR_NEKVECTOR_MAX_UNROLL_ARGS, NEKTAR_NEKVECTOR_UNROLL_IMPL, Unroll);
651 template<
typename LhsType,
typename Op,
typename RhsType,
typename IndicesType,
unsigned int index>
652 struct BinaryBinaryEvaluateNodeOverride<LhsType, Op, RhsType, IndicesType, index,
653 typename boost::enable_if
655 NodeCanUnroll<expt::Node<LhsType, Op, RhsType> >
656 >::type> :
public boost::true_type
658 static const int endIndex = index + LhsType::TotalCount + RhsType::TotalCount;
660 template<
typename ResultType,
typename ArgumentVectorType>
661 static inline void Evaluate(ResultType& accumulator,
const ArgumentVectorType& args)
663 Unroll<IndicesType, index, endIndex>::Execute(accumulator, args);
667 #endif //NEKTAR_USE_EXPRESSION_TEMPLATES
670 #endif // NEKTAR_LIB_UTILITIES_NEK_VECTOR_HPP