diff --git a/AMDiS/src/GenericOperatorTerm.h b/AMDiS/src/GenericOperatorTerm.h index e677e8b07edcc72410bcfec250f89d317196ae65..de504250e75fab48639a9831130c7318797a049d 100644 --- a/AMDiS/src/GenericOperatorTerm.h +++ b/AMDiS/src/GenericOperatorTerm.h @@ -36,6 +36,7 @@ #include "expressions/LazyOperatorTerm.h" #include "expressions/AtomicExpression.h" #include "expressions/LazyExpression.h" +#include "expressions/cmath_expr.h" /** generic operator-terms provide an easy way of automated generation of * 'arbitrary' operator-terms out of some elementary operations, by using a @@ -767,13 +768,28 @@ inline void addSOT(Operator& op, double term, int I, int J) addSOT(op, constant(term), I, J); } + +// _____________________________________________________________________________ + + +template<typename TOut> +inline result_of::Function1<result_of::Wrapper<TOut,WorldVector<double> >, result_of::Coords> +eval(AbstractFunction<TOut, WorldVector<double> >* fct) { return function_(wrap(fct), X()); } + +// C++11: +// template<typename TOut> +// inline auto eval(AbstractFunction<TOut, WorldVector<double> >* fct) -> decltype( function_(wrap(fct), X()) ) +// { return function_(wrap(fct), X()); } + + + template<typename Term> inline typename boost::enable_if<typename boost::is_base_of<LazyOperatorTermBase, Term>::type, typename Term::value_type>::type integrate(Term term); template<typename Term> -inline typename boost::enable_if<typename boost::is_base_of<LazyOperatorTermBase, Term>::type, typename Term::value_type>::type +inline typename boost::enable_if<typename boost::is_base_of<LazyOperatorTermBase, Term>::type, void>::type transformDOF(Term term, DOFVector<typename Term::value_type>* result); template<typename Term> diff --git a/AMDiS/src/GenericOperatorTerm.hh b/AMDiS/src/GenericOperatorTerm.hh index 4d33f0b90ba1a298a1eceb06af13d48f456e578e..2bb86b179ef84cc257df66a8bdfac97851df9a8d 100644 --- a/AMDiS/src/GenericOperatorTerm.hh +++ b/AMDiS/src/GenericOperatorTerm.hh @@ -53,13 +53,15 @@ namespace AMDiS { template<typename Term> inline typename boost::enable_if<typename boost::is_base_of<LazyOperatorTermBase, Term>::type, typename Term::value_type>::type -integrate(Term term) +integrate(Term term, Mesh* mesh_ = NULL) { typedef typename Term::value_type TOut; typename GenericOperatorTerm<Term>::type ot(term); std::set<const FiniteElemSpace*> feSpaces = ot.getAuxFeSpaces(); - Mesh* mesh = (*feSpaces.begin())->getMesh(); + + TEST_EXIT(mesh_ || !feSpaces.empty())("The Expression must contain a DOFVector or FeSpace depended value!\n"); + Mesh* mesh = mesh_ ? mesh_ : (*feSpaces.begin())->getMesh(); int deg = term.getDegree(); int dim = mesh->getDim(); @@ -91,23 +93,24 @@ integrate(Term term) // works only for nodal basis functions! template<typename Term> -inline typename boost::enable_if<typename boost::is_base_of<LazyOperatorTermBase, Term>::type, typename Term::value_type>::type +inline typename boost::enable_if<typename boost::is_base_of<LazyOperatorTermBase, Term>::type, void>::type transformDOF(Term term, DOFVector<typename Term::value_type>* result) { typedef typename Term::value_type TOut; TOut tmp; nullify(tmp); + DOFVector<TOut> temp(result->getFeSpace(), "temp"); + DOFVector<short int> assigned(result->getFeSpace(), "assigned"); + typename GenericOperatorTerm<Term>::type ot(term); - std::set<const FiniteElemSpace*> feSpaces = ot.getAuxFeSpaces(); - Mesh* mesh = (*feSpaces.begin())->getMesh(); + Mesh* mesh = result->getFeSpace()->getMesh(); - const FiniteElemSpace* resultFeSpace = result->getFeSpace(); + const FiniteElemSpace* resultFeSpace = temp.getFeSpace(); const BasisFunction *basisFcts = resultFeSpace->getBasisFcts(); int nBasisFcts = basisFcts->getNumber(); - DOFVector<short int> assigned(resultFeSpace, "assigned"); assigned.set(0); - result->set(tmp); + temp.set(tmp); std::vector<DegreeOfFreedom> localIndices(nBasisFcts); TraverseStack stack; @@ -120,16 +123,17 @@ transformDOF(Term term, DOFVector<typename Term::value_type>* result) basisFcts->getLocalIndices(elInfo->getElement(), resultFeSpace->getAdmin(), localIndices); for (int i = 0; i < nBasisFcts; i++) { - (*result)[localIndices[i]] += term(i); + temp[localIndices[i]] += term(i); assigned[localIndices[i]]++; } elInfo = stack.traverseNext(elInfo); - } + } - DOFIterator<typename Term::value_type> resultIter(result, USED_DOFS); + DOFIterator<TOut> tempIter(&temp, USED_DOFS); + DOFIterator<TOut> resultIter(result, USED_DOFS); DOFIterator<short int> assignedIter(&assigned, USED_DOFS); - for (resultIter.reset(), assignedIter.reset(); !resultIter.end(); ++resultIter, ++assignedIter) { - *resultIter *= 1.0/static_cast<double>(*assignedIter); + for (tempIter.reset(), resultIter.reset(), assignedIter.reset(); !resultIter.end(); ++tempIter, ++resultIter, ++assignedIter) { + *resultIter = (*tempIter)/static_cast<double>(*assignedIter); } } diff --git a/AMDiS/src/expressions/AtomicExpression.h b/AMDiS/src/expressions/AtomicExpression.h index 93233b8250cdc9a1fd50d53820bab9308a021709..2e9b0bee1aac4f39b507bb55766f0a2410ace03d 100644 --- a/AMDiS/src/expressions/AtomicExpression.h +++ b/AMDiS/src/expressions/AtomicExpression.h @@ -36,6 +36,34 @@ namespace AMDiS { +namespace traits { + + template<typename T> + struct ValueType { + typedef T type; + static type eval(const T& t) { return t; } + }; + + template<typename T> + struct ValueType<T&> { + typedef typename ValueType<T>::type type; + static type eval(T& t) { return t; } + }; + + template<typename T> + struct ValueType<T*> { + typedef typename ValueType<T>::type type; + static type eval(T* t) { return ValueType<T>::eval(*t); } + }; + + template<typename T> + struct ValueType<const T> { + typedef typename ValueType<T>::type type; + static type eval(const T& t) { return ValueType<T>::eval(t); } + }; + +} + namespace result_of { /// initialize a coordinate vector at quadrature points @@ -75,7 +103,6 @@ namespace result_of { x.change_dim(nBasisFct); for (int i = 0; i < nBasisFct; i++) elInfo->coordToWorld(*basisFct->getCoords(i), x[i]); - MSG("elInfo->coordToWorld(basisFct)\n"); } } @@ -105,7 +132,9 @@ namespace result_of { } inline value_type operator()(const int& iq) const { return x[iq]; } - inline value_type derivative(const int& iq, int identifier) const { WorldVector<double> vec0; vec0.set(0.0); return vec0; } + + template<typename Identifier> + inline value_type derivative(const int& iq) const { WorldVector<double> vec0; vec0.set(0.0); return vec0; } }; @@ -174,7 +203,9 @@ namespace result_of { } inline double operator()(const int& iq) const { return x[iq][I]; } - inline double derivative(const int& iq, int identifier) const { return 0.0; } + + template<typename Identifier> + inline double derivative(const int& iq) const { return 0.0; } }; @@ -213,7 +244,9 @@ namespace result_of { } inline value_type operator()(const int& iq) const { return normal; } - inline value_type derivative(const int& iq, int identifier) const { WorldVector<double> vec0; vec0.set(0.0); return vec0; } + + template<typename Identifier> + inline value_type derivative(const int& iq) const { WorldVector<double> vec0; vec0.set(0.0); return vec0; } }; @@ -252,7 +285,9 @@ namespace result_of { } inline value_type operator()(const int& iq) const { return normal[I]; } - inline value_type derivative(const int& iq, int identifier) const { return 0.0; } + + template<typename Identifier> + inline value_type derivative(const int& iq) const { return 0.0; } }; @@ -291,7 +326,9 @@ namespace result_of { } inline value_type operator()(const int& iq) const { return elementNormal; } - inline value_type derivative(const int& iq, int identifier) const { WorldVector<double> vec0; vec0.set(0.0); return vec0; } + + template<typename Identifier> + inline value_type derivative(const int& iq) const { WorldVector<double> vec0; vec0.set(0.0); return vec0; } }; @@ -329,7 +366,9 @@ namespace result_of { } inline value_type operator()(const int& iq) const { return elementNormal[I]; } - inline value_type derivative(const int& iq, int identifier) const { return 0.0; } + + template<typename Identifier> + inline value_type derivative(const int& iq) const { return 0.0; } }; @@ -359,22 +398,54 @@ namespace result_of { const BasisFunction *basisFct = NULL) {} inline value_type operator()(const int& iq) const { return value; } - inline value_type derivative(const int& iq, int identifier) const { return 0.0; } + + template<typename Identifier> + inline value_type derivative(const int& iq) const { return 0.0; } }; + template<typename T> + struct Reference : public LazyOperatorTermBase + { + typedef typename ValueType<T>::type value_type; + const value_type& value; + Reference(const T& value_) : value(value_) {} + Reference(const T* value_) : value(*value_) {} + + template<typename List> + void insertFeSpaces(List& feSpaces) const {} + + int getDegree() const + { + return 0; + } + + template<typename OT> + void initElement(OT* ot, const ElInfo* elInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) {} + + template<typename OT> + void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) {} + + inline value_type operator()(const int& iq) const { return value; } + + template<typename Identifier> + inline value_type derivative(const int& iq) const { return 0.0; } + }; + /// - template<typename Term> + template<typename Term, typename Identifier> struct Jacobian : public LazyOperatorTerm1<Term> { typedef LazyOperatorTerm1<Term> super; typedef typename Term::value_type value_type; - - const int I; - - Jacobian(const Term& term_, int I_) : super(term_), I(I_) {} + + Jacobian(const Term& term_) : super(term_) {} int getDegree() const { @@ -382,7 +453,7 @@ namespace result_of { return super::term.getDegree(); } - inline value_type operator()(const int& iq) const { return super::term.derivative(iq, I); } + inline value_type operator()(const int& iq) const { return super::term.template derivative<Identifier>(iq); } }; } @@ -400,13 +471,18 @@ inline result_of::ElementNormal M(int I) { return result_of::ElementNormal(I); } template<typename T> inline result_of::Const<T> constant(const T& value) { return result_of::Const<T>(value); } +template<typename T> +inline result_of::Reference<T> ref_(T& value) { return result_of::Reference<T>(value); } +template<typename T> +inline result_of::Reference<T> ref_(T* value) { return result_of::Reference<T>(value); } + namespace Private { - template<typename Term> + template<typename Identifier, typename Term> inline typename boost::enable_if< typename boost::is_base_of<LazyOperatorTermBase, Term>::type, - result_of::Jacobian<Term> >::type - jacobian(const Term& t, int I) { return result_of::Jacobian<Term>(t, I); } + result_of::Jacobian<Term, Identifier> >::type + jacobian(const Term& t) { return result_of::Jacobian<Term, Identifier>(t); } } diff --git a/AMDiS/src/expressions/LazyExpression.h b/AMDiS/src/expressions/LazyExpression.h index f053bccb204adec366f77dfa95d7b139abd4c4e7..c2f5a0c993d3bc40729ebb6251891b69589f7a89 100644 --- a/AMDiS/src/expressions/LazyExpression.h +++ b/AMDiS/src/expressions/LazyExpression.h @@ -52,118 +52,6 @@ protected: namespace result_of { - - /// - template<int I, typename Term> - struct Pow : public LazyOperatorTerm1<Term> - { - typedef LazyOperatorTerm1<Term> super; - typedef typename AMDiS::detail::Pow<I,typename Term::value_type>::result_type value_type; - - Pow(const Term& term_) : super(term_) {} - - int getDegree() const - { - return I * (super::term.getDegree()); - } - - inline value_type operator()(const int& iq) const { return AMDiS::detail::Pow<I,typename Term::value_type>::eval(super::term(iq)); } - inline value_type derivative(const int& iq, int identifier) const - { - return super::term.derivative(iq, identifier) * I*AMDiS::detail::Pow<I-1,typename Term::value_type>::eval(super::term(iq)); - } - }; - - - /// - template<typename Term> - struct Sqrt : public LazyOperatorTerm1<Term> - { - typedef LazyOperatorTerm1<Term> super; - typedef typename Term::value_type value_type; - - Sqrt(const Term& term_) : super(term_) {} - - int getDegree() const - { - return 2 * (super::term.getDegree()); // stimmt nicht ganz - } - - inline value_type operator()(const int& iq) const { return sqrt(super::term(iq)); } - - inline value_type derivative(const int& iq, int identifier) const - { - return super::term.derivative(iq, identifier) / (2.0 * sqrt(super::term(iq))); - } - }; - - - /// - template<typename Term> - struct Exp : public LazyOperatorTerm1<Term> - { - typedef LazyOperatorTerm1<Term> super; - typedef typename Term::value_type value_type; - int degree; - - Exp(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} - - int getDegree() const - { - return degree * (super::term.getDegree()); - } - - inline value_type operator()(const int& iq) const { return exp(super::term(iq)); } - - inline value_type derivative(const int& iq, int identifier) const - { - return super::term.derivative(iq, identifier) * exp(super::term(iq)); - } - }; - - - /// - template<typename Term> - struct Abs : public LazyOperatorTerm1<Term> - { - typedef LazyOperatorTerm1<Term> super; - typedef typename Term::value_type value_type; - - Abs(const Term& term_) : super(term_) {} - - int getDegree() const - { - return super::term.getDegree(); - } - - inline value_type operator()(const int& iq) const { return std::abs(super::term(iq)); } - - inline value_type derivative(const int& iq, int identifier) const - { - return super::term(iq) > 0.0 ? super::term.derivative(iq, identifier) : -super::term.derivative(iq, identifier); - } - }; - - - /// - template<typename Term> - struct Signum : public LazyOperatorTerm1<Term> - { - typedef LazyOperatorTerm1<Term> super; - typedef typename Term::value_type value_type; - - Signum(const Term& term_) : super(term_) {} - - int getDegree() const - { - return 0; - } - - inline value_type operator()(const int& iq) const { return (super::term(iq) > 0.0 ? 1.0 : -1.0); } - - inline value_type derivative(const int& iq, int identifier) const { return 0.0; } - }; - /// template<typename Term1, typename Term2> @@ -182,9 +70,24 @@ namespace result_of { inline value_type operator()(const int& iq) const { return super::term1(iq) + super::term2(iq); } - inline value_type derivative(const int& iq, int identifier) const + template<typename Identifier> + inline value_type derivative(const int& iq) const + { + return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, super>::type()); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::true_) const { - return super::term1.derivative(iq, identifier) + super::term2.derivative(iq, identifier); + return super::term1.derivative<Identifier>(iq) + super::term2.derivative<Identifier>(iq); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::false_) const + { + value_type result; + nullify(result); + return result; } }; @@ -207,9 +110,24 @@ namespace result_of { inline value_type operator()(const int& iq) const { return super::term1(iq) * super::term2(iq); } - inline value_type derivative(const int& iq, int identifier) const + template<typename Identifier> + inline value_type derivative(const int& iq) const + { + return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, super>::type()); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::true_) const { - return super::term1.derivative(iq, identifier) * super::term2(iq) + super::term1(iq) * super::term2.derivative(iq, identifier); + return super::term1.derivative<Identifier>(iq) * super::term2(iq) + super::term1(iq) * super::term2.derivative<Identifier>(iq); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::false_) const + { + value_type result; + nullify(result); + return result; } }; @@ -232,64 +150,25 @@ namespace result_of { inline value_type operator()(const int& iq) const { return super::term1(iq) / super::term2(iq); } - inline value_type derivative(const int& iq, int identifier) const + template<typename Identifier> + inline value_type derivative(const int& iq) const { - typename Term2::value_type term2_eval = super::term2(iq); - return (super::term1.derivative(iq, identifier) * term2_eval - super::term1(iq) * super::term2.derivative(iq, identifier)) / (sqr(term2_eval)); - } - }; - - - /// - template<typename Term1, typename Term2> - struct Max : public LazyOperatorTerm2<Term1, Term2> - { - typedef LazyOperatorTerm2<Term1, Term2> super; - typedef typename Term1::value_type value_type; - - Max(const Term1& term1_, const Term2& term2_) - : super(term1_, term2_) {} - - int getDegree() const - { - return std::max(super::term1.getDegree(), super::term2.getDegree()); - } - - inline value_type operator()(const int& iq) const - { - return std::max(super::term1(iq), super::term2(iq)); + return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, super>::type()); } - inline value_type derivative(const int& iq, int identifier) const + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::true_) const { - return super::term1(iq) > super::term2(iq) ? super::term1.derivative(iq, identifier) : super::term2.derivative(iq, identifier); - } - }; - - - /// - template<typename Term1, typename Term2> - struct Min : public LazyOperatorTerm2<Term1, Term2> - { - typedef LazyOperatorTerm2<Term1, Term2> super; - typedef typename Term1::value_type value_type; - - Min(const Term1& term1_, const Term2& term2_) - : super(term1_, term2_) {} - - int getDegree() const - { - return std::max(super::term1.getDegree(), super::term2.getDegree()); - } - - inline value_type operator()(const int& iq) const - { - return std::min(super::term1(iq), super::term2(iq)); + typename Term2::value_type term2_eval = super::term2(iq); + return (super::term1.derivative<Identifier>(iq) * term2_eval - super::term1(iq) * super::term2.derivative<Identifier>(iq)) / (sqr(term2_eval)); } - inline value_type derivative(const int& iq, int identifier) const + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::false_) const { - return super::term1(iq) < super::term2(iq) ? super::term1.derivative(iq, identifier) : super::term2.derivative(iq, identifier); + value_type result; + nullify(result); + return result; } }; @@ -314,7 +193,25 @@ namespace result_of { inline value_type operator()(const int& iq) const { return f(super::term(iq)); } - inline value_type derivative(const int& iq, int identifier) const { return super::term.derivative(iq, identifier) * f.derivative<0>(super::term(iq)); } + template<typename Identifier> + inline value_type derivative(const int& iq) const + { + return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, super>::type()); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::true_) const + { + return super::term.derivative<Identifier>(iq) * f.derivative<0>(super::term(iq)); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::false_) const + { + value_type result; + nullify(result); + return result; + } }; @@ -338,11 +235,26 @@ namespace result_of { } inline value_type operator()(const int& iq) const { return f(super::term1(iq), super::term2(iq)); } + + template<typename Identifier> + inline value_type derivative(const int& iq) const + { + return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, super>::type()); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::true_) const + { + return super::term1.derivative<Identifier>(iq) * f.derivative<0>(super::term1(iq), super::term2(iq)) + +super::term2.derivative<Identifier>(iq) * f.derivative<1>(super::term1(iq), super::term2(iq)); + } - inline value_type derivative(const int& iq, int identifier) const + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::false_) const { - return super::term1.derivative(iq, identifier) * f.derivative<0>(super::term1(iq), super::term2(iq)) - +super::term2.derivative(iq, identifier) * f.derivative<1>(super::term1(iq), super::term2(iq)); + value_type result; + nullify(result); + return result; } }; @@ -369,15 +281,77 @@ namespace result_of { inline value_type operator()(const int& iq) const { return f(super::term1(iq), super::term2(iq), super::term3(iq)); } - inline value_type derivative(const int& iq, int identifier) const + template<typename Identifier> + inline value_type derivative(const int& iq) const + { + return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, super>::type()); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::true_) const + { + return super::term1.derivative<Identifier>(iq) * f.derivative<0>(super::term1(iq), super::term2(iq), super::term3(iq)) + +super::term2.derivative<Identifier>(iq) * f.derivative<1>(super::term1(iq), super::term2(iq), super::term3(iq)) + +super::term3.derivative<Identifier>(iq) * f.derivative<2>(super::term1(iq), super::term2(iq), super::term3(iq)); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::false_) const { - return super::term1.derivative(iq, identifier) * f.derivative<0>(super::term1(iq), super::term2(iq), super::term3(iq)) - +super::term2.derivative(iq, identifier) * f.derivative<1>(super::term1(iq), super::term2(iq), super::term3(iq)) - +super::term3.derivative(iq, identifier) * f.derivative<2>(super::term1(iq), super::term2(iq), super::term3(iq)); + value_type result; + nullify(result); + return result; } }; + + template<typename TOut, typename TIn> + struct Wrapper : public FunctorBase + { + typedef TOut value_type; + Wrapper(AbstractFunction<TOut, TIn>* fct_) : fct(fct_) {} + int getDegree(int degree) const { return fct->getDegree(); } + + TOut operator()(const TIn& x) const + { + return (*fct)(x); + } + + protected: + AbstractFunction<TOut, TIn>* fct; + }; } + +namespace traits +{ + + template<typename Identifier, typename Term1, typename Term2> + struct DependsOn<Identifier, AMDiS::result_of::Add<Term1, Term2> > + : public DependsOn<Identifier, LazyOperatorTerm2<Term1, Term2> >::type {}; + + template<typename Identifier, typename Term1, typename Term2> + struct DependsOn<Identifier, AMDiS::result_of::Mult<Term1, Term2> > + : public DependsOn<Identifier, LazyOperatorTerm2<Term1, Term2> >::type {}; + + template<typename Identifier, typename Term1, typename Term2> + struct DependsOn<Identifier, AMDiS::result_of::Divide<Term1, Term2> > + : public DependsOn<Identifier, LazyOperatorTerm2<Term1, Term2> >::type {}; + + + template<typename Identifier, typename F, typename Term> + struct DependsOn<Identifier, AMDiS::result_of::Function1<F, Term> > + : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; + + template<typename Identifier, typename F, typename Term1, typename Term2> + struct DependsOn<Identifier, AMDiS::result_of::Function2<F, Term1, Term2> > + : public DependsOn<Identifier, LazyOperatorTerm2<Term1, Term2> >::type {}; + + template<typename Identifier, typename F, typename Term1, typename Term2, typename Term3> + struct DependsOn<Identifier, AMDiS::result_of::Function3<F, Term1, Term2, Term3> > + : public DependsOn<Identifier, LazyOperatorTerm3<Term1, Term2, Term3> >::type {}; +} + + // add two terms template<typename Term1, typename Term2> inline typename boost::enable_if< @@ -502,93 +476,8 @@ inline typename boost::enable_if< result_of::Divide<Term, result_of::Const<T> > >::type operator/(const Term& t1, const T& t2) { return divide(t1, constant(t2)); } -// maximum of two terms -template<typename Term1, typename Term2> -inline typename boost::enable_if< - typename boost::mpl::and_<typename boost::is_base_of<LazyOperatorTermBase, Term1>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term2>::type>::type, - result_of::Max<Term1, Term2> >::type -max(const Term1& t1, const Term2& t2) { return result_of::Max<Term1, Term2>(t1, t2); } - -template<typename T, typename Term> -inline typename boost::enable_if< - typename boost::mpl::and_<typename boost::is_fundamental<T>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term>::type>::type, - result_of::Max<result_of::Const<T>, Term> >::type -max(const T& t1, const Term& t2) { return result_of::Max<result_of::Const<T>, Term>(constant(t1), t2); } - -template<typename Term, typename T> -inline typename boost::enable_if< - typename boost::mpl::and_<typename boost::is_fundamental<T>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term>::type>::type, - result_of::Max<Term, result_of::Const<T> > >::type -max(const Term& t1, const T& t2) { return result_of::Max<Term, result_of::Const<T> >(t1, constant(t2)); } - - - -// minimum of two terms -template<typename Term1, typename Term2> -inline typename boost::enable_if< - typename boost::mpl::and_<typename boost::is_base_of<LazyOperatorTermBase, Term1>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term2>::type>::type, - result_of::Min<Term1, Term2> >::type -min(const Term1& t1, const Term2& t2) { return result_of::Min<Term1, Term2>(t1, t2); } - -template<typename T, typename Term> -inline typename boost::enable_if< - typename boost::mpl::and_<typename boost::is_fundamental<T>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term>::type>::type, - result_of::Min<result_of::Const<T>, Term> >::type -min(const T& t1, const Term& t2) { return result_of::Max<result_of::Const<T>, Term>(constant(t1), t2); } - -template<typename Term, typename T> -inline typename boost::enable_if< - typename boost::mpl::and_<typename boost::is_fundamental<T>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term>::type>::type, - result_of::Min<Term, result_of::Const<T> > >::type -min(const Term& t1, const T& t2) { return result_of::Min<Term, result_of::Const<T> >(t1, constant(t2)); } - - -// I'th power of a term -template<int I, typename Term> -inline typename boost::enable_if< - typename boost::is_base_of<LazyOperatorTermBase, Term>::type, - result_of::Pow<I, Term> >::type -pow(const Term& t) { return result_of::Pow<I, Term>(t); } - - -// square root of a term -template<typename Term> -inline typename boost::enable_if< - typename boost::is_base_of<LazyOperatorTermBase, Term>::type, - result_of::Sqrt<Term> >::type -sqrt(const Term& t) { return result_of::Sqrt<Term>(t); } - - -// exponential function of a term -template<typename Term> -inline typename boost::enable_if< - typename boost::is_base_of<LazyOperatorTermBase, Term>::type, - result_of::Exp<Term> >::type -exp(const Term& t) { return result_of::Exp<Term>(t); } - - -// absolute value of a term -template<typename Term> -inline typename boost::enable_if< - typename boost::is_base_of<LazyOperatorTermBase, Term>::type, - result_of::Abs<Term> >::type -abs_(const Term& t) { return result_of::Abs<Term>(t); } // TODO: Funktionsnamen ohne Unterstrich - - -// signum of a term -template<typename Term> -inline typename boost::enable_if< - typename boost::is_base_of<LazyOperatorTermBase, Term>::type, - result_of::Signum<Term> >::type -signum(const Term& t) { return result_of::Signum<Term>(t); } - +// _____________________________________________________________________________ // call a function with 1 argument template<typename F, typename Term> @@ -649,6 +538,10 @@ typename boost::enable_if< >::type function_(const Term1& t1, const Term2& t2, const Term3& t3) { return result_of::Function3<F,Term1,Term2,Term3>(F(),t1,t2,t3); } + +template<typename TOut, typename TIn> +inline result_of::Wrapper<TOut,TIn> wrap(AbstractFunction<TOut, TIn>* fct) { return result_of::Wrapper<TOut,TIn>(fct); } + } // end namespace AMDiS #endif \ No newline at end of file diff --git a/AMDiS/src/expressions/LazyOperatorTerm.h b/AMDiS/src/expressions/LazyOperatorTerm.h index 6dd75db8cf772274c404cf116a2a8edc17ac76df..16e9ef567d4cef83804eaa1d04100d4c950adbc2 100644 --- a/AMDiS/src/expressions/LazyOperatorTerm.h +++ b/AMDiS/src/expressions/LazyOperatorTerm.h @@ -142,6 +142,31 @@ struct LazyOperatorTerm3 : public LazyOperatorTermBase inline double operator()(const int& iq) const; }; + +namespace traits +{ + template<typename Identifier, typename T> + struct DependsOn : public boost::mpl::bool_<false> {}; + + template<typename Identifier, typename Term> + struct DependsOn<Identifier, LazyOperatorTerm1<Term> > + : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; + + template<typename Identifier, typename Term1, typename Term2> + struct DependsOn<Identifier, LazyOperatorTerm2<Term1, Term2> > + : public boost::mpl::bool_< boost::mpl::or_< + typename DependsOn<Identifier, Term1>::type, + typename DependsOn<Identifier, Term2>::type>::type::value > {}; + + template<typename Identifier, typename Term1, typename Term2, typename Term3> + struct DependsOn<Identifier, LazyOperatorTerm3<Term1, Term2, Term3> > + : public boost::mpl::bool_< boost::mpl::or_< + typename DependsOn<Identifier, Term1>::type, + typename DependsOn<Identifier, Term2>::type, + typename DependsOn<Identifier, Term3>::type>::type::value > {}; +} + + } // end namespace AMDiS #endif \ No newline at end of file diff --git a/AMDiS/src/expressions/ValueOf.h b/AMDiS/src/expressions/ValueOf.h index c8cf010c7c7e1029897575bf83ef2409849e93fa..3974d4fb4d64a87f36914d814af5548389927d89 100644 --- a/AMDiS/src/expressions/ValueOf.h +++ b/AMDiS/src/expressions/ValueOf.h @@ -31,17 +31,21 @@ #include "DOFVector.h" #include <boost/static_assert.hpp> +#include <boost/mpl/bool.hpp> namespace AMDiS { + +struct _unknown {}; namespace result_of { + - template<typename Vector> + template<typename Vector, typename Name> struct ValueOf : public LazyOperatorTermBase {}; - template<typename T> - struct ValueOf<DOFVector<T> > : public LazyOperatorTermBase + template<typename T, typename Name> + struct ValueOf<DOFVector<T>, Name> : public LazyOperatorTermBase { typedef T value_type; @@ -113,12 +117,14 @@ namespace result_of { } inline value_type operator()(const int& iq) const { return vec[iq]; } - inline value_type derivative(const int& iq, int identifier) const { return 0.0; } + + template<typename Identifier> + inline value_type derivative(const int& iq) const { return ( boost::is_same<Identifier, Name>::type::value ? 1.0 : 0.0 ); } }; - template<template<class> class Vector, typename T> - struct ValueOf<Vector<DOFVector<T>*> > : public LazyOperatorTermBase + template<template<class> class Vector, typename T, typename Name> + struct ValueOf<Vector<DOFVector<T>*>, Name> : public LazyOperatorTermBase { typedef Vector<T> value_type; @@ -213,7 +219,16 @@ namespace result_of { } inline value_type operator()(const int& iq) const { return vec[iq]; } - inline value_type derivative(const int& iq, int identifier) const { return 0.0; } + + template<typename Identifier> + inline value_type derivative(const int& iq) const { + value_type result; result.set(1.0); + if (boost::is_same<Identifier, Name>::type::value) + result.set(1.0); + else + nullify(result); + return result; + } }; @@ -294,21 +309,52 @@ namespace result_of { } inline value_type operator()(const int& iq) const { return vec[iq][I]; } - inline value_type derivative(const int& iq, int identifier) const { return 0.0; } + + template<typename Identifier> + inline value_type derivative(const int& iq) const { return 0.0; } }; } // end namespace result_of +namespace traits { + + template<typename Identifier, typename T, typename Name> + struct DependsOn<Identifier, AMDiS::result_of::ValueOf<T, Name> > : public boost::is_same<Identifier, Name> {}; + +} + + +#if __cplusplus > 199711L +template<typename Name = _unknown, typename T> +result_of::ValueOf<DOFVector<T>, Name > valueOf(DOFVector<T>& vector) { return result_of::ValueOf<DOFVector<T>, Name >(vector); } + +template<typename Name = _unknown, typename T> +result_of::ValueOf<DOFVector<T>, Name > valueOf(DOFVector<T>* vector) { return result_of::ValueOf<DOFVector<T>, Name >(vector); } + +template<typename Name = _unknown, template<class> class Vector, typename T> +result_of::ValueOf<Vector<DOFVector<T>*>, Name > valueOf(Vector<DOFVector<T>*> &vector) { return result_of::ValueOf<Vector<DOFVector<T>*>, Name >(vector); } +#else +// with Name +template<typename Name, typename T> +result_of::ValueOf<DOFVector<T>, Name > valueOf(DOFVector<T>& vector) { return result_of::ValueOf<DOFVector<T>, Name >(vector); } + +template<typename Name, typename T> +result_of::ValueOf<DOFVector<T>, Name > valueOf(DOFVector<T>* vector) { return result_of::ValueOf<DOFVector<T>, Name >(vector); } + +template<typename Name, template<class> class Vector, typename T> +result_of::ValueOf<Vector<DOFVector<T>*>, Name > valueOf(Vector<DOFVector<T>*> &vector) { return result_of::ValueOf<Vector<DOFVector<T>*>, Name >(vector); } +// without Name template<typename T> -result_of::ValueOf<DOFVector<T> > valueOf(DOFVector<T>& vector) { return result_of::ValueOf<DOFVector<T> >(vector); } +result_of::ValueOf<DOFVector<T>, _unknown > valueOf(DOFVector<T>& vector) { return result_of::ValueOf<DOFVector<T>, _unknown >(vector); } template<typename T> -result_of::ValueOf<DOFVector<T> > valueOf(DOFVector<T>* vector) { return result_of::ValueOf<DOFVector<T> >(vector); } +result_of::ValueOf<DOFVector<T>, _unknown > valueOf(DOFVector<T>* vector) { return result_of::ValueOf<DOFVector<T>, _unknown >(vector); } template<template<class> class Vector, typename T> -result_of::ValueOf<Vector<DOFVector<T>*> > valueOf(Vector<DOFVector<T>*> &vector) { return result_of::ValueOf<Vector<DOFVector<T>*> >(vector); } +result_of::ValueOf<Vector<DOFVector<T>*>, _unknown > valueOf(Vector<DOFVector<T>*> &vector) { return result_of::ValueOf<Vector<DOFVector<T>*>, _unknown >(vector); } +#endif template<template<class> class Vector, typename T> result_of::ComponentOf<DOFVector<Vector<T> > > componentOf(DOFVector<Vector<T> >& vector, int I) { return result_of::ComponentOf<DOFVector<Vector<T> > >(vector, I); } diff --git a/AMDiS/src/expressions/cmath_expr.h b/AMDiS/src/expressions/cmath_expr.h new file mode 100644 index 0000000000000000000000000000000000000000..4af0f07d176b345d6de304a4c0389473e60fa335 --- /dev/null +++ b/AMDiS/src/expressions/cmath_expr.h @@ -0,0 +1,1185 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + + +/** \file cmath_expr.h */ + +#ifndef AMDIS_CMATH_EXPRESSION_H +#define AMDIS_CMATH_EXPRESSION_H + +#include "AMDiS_fwd.h" +#include "LazyOperatorTerm.h" +#include "ValueTypes.h" +#include "Functors.h" + +#include <boost/static_assert.hpp> + + +namespace AMDiS { + +namespace result_of { + + + + /// + template<typename Term> + struct Abs : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + + Abs(const Term& term_) : super(term_) {} + + int getDegree() const + { + return super::term.getDegree(); + } + + inline value_type operator()(const int& iq) const { return std::abs(super::term(iq)); } + + template<typename Identifier> + inline value_type derivative(const int& iq) const + { + return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, Term>::type()); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::true_) const + { + return super::term(iq) > 0.0 ? super::term.derivative<Identifier>(iq) : -super::term.derivative<Identifier>(iq); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::false_) const + { + value_type result; + nullify(result); + return result; + } + }; + + + /// + template<typename Term> + struct Signum : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + + Signum(const Term& term_) : super(term_) {} + + int getDegree() const + { + return 0; + } + + inline value_type operator()(const int& iq) const { return (super::term(iq) > 0.0 ? 1.0 : -1.0); } + + template<typename Identifier> + inline value_type derivative(const int& iq) const + { + value_type result; + nullify(result); + return result; + } + }; + + + + /// + template<typename Term> + struct Ceil : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + + Ceil(const Term& term_) : super(term_) {} + + int getDegree() const { return 0; } + + inline value_type operator()(const int& iq) const { return ceil(super::term(iq)); } + + template<typename Identifier> + inline value_type derivative(const int& iq) const + { + value_type result; + nullify(result); + return result; + } + }; + + + /// + template<typename Term> + struct Floor : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + + Floor(const Term& term_) : super(term_) {} + + int getDegree() const { return 0; } + + inline value_type operator()(const int& iq) const { return floor(super::term(iq)); } + + template<typename Identifier> + inline value_type derivative(const int& iq) const + { + value_type result; + nullify(result); + return result; + } + }; + + + // ___________________________________________________________________________ + + + /// + template<int I, typename Term> + struct Pow : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename AMDiS::detail::Pow<I,typename Term::value_type>::result_type value_type; + + Pow(const Term& term_) : super(term_) {} + + int getDegree() const + { + return I * (super::term.getDegree()); + } + + inline value_type operator()(const int& iq) const { return AMDiS::detail::Pow<I,typename Term::value_type>::eval(super::term(iq)); } + + template<typename Identifier> + inline value_type derivative(const int& iq) const + { + return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, Term>::type()); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::true_) const + { + return super::term.derivative<Identifier>(iq) * I*AMDiS::detail::Pow<I-1,typename Term::value_type>::eval(super::term(iq)); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::false_) const + { + value_type result; + nullify(result); + return result; + } + }; + + + /// + template<typename Term> + struct Sqrt : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + + Sqrt(const Term& term_) : super(term_) {} + + int getDegree() const + { + return 2 * (super::term.getDegree()); // stimmt nicht ganz + } + + inline value_type operator()(const int& iq) const { return sqrt(super::term(iq)); } + + template<typename Identifier> + inline value_type derivative(const int& iq) const + { + return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, Term>::type()); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::true_) const + { + return super::term.derivative<Identifier>(iq) / (2.0 * sqrt(super::term(iq))); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::false_) const + { + value_type result; + nullify(result); + return result; + } + }; + + + // ___________________________________________________________________________ + + /// + template<typename Term> + struct Exp : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + int degree; + + Exp(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} + + int getDegree() const + { + return degree * (super::term.getDegree()); + } + + inline value_type operator()(const int& iq) const { return exp(super::term(iq)); } + + + template<typename Identifier> + inline value_type derivative(const int& iq) const + { + return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, Term>::type()); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::true_) const + { + return super::term.derivative<Identifier>(iq) * exp(super::term(iq)); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::false_) const + { + value_type result; + nullify(result); + return result; + } + }; + + /// + template<typename Term> + struct Log : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + int degree; + + Log(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} + + int getDegree() const + { + return degree * (super::term.getDegree()); + } + + inline value_type operator()(const int& iq) const { return log(super::term(iq)); } + + + template<typename Identifier> + inline value_type derivative(const int& iq) const + { + return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, Term>::type()); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::true_) const + { + return super::term.derivative<Identifier>(iq) / (super::term(iq)); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::false_) const + { + value_type result; + nullify(result); + return result; + } + }; + + // ___________________________________________________________________________ + + + /// + template<typename Term> + struct Cos : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + int degree; + + Cos(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} + + int getDegree() const + { + return degree * (super::term.getDegree()); + } + + inline value_type operator()(const int& iq) const { return cos(super::term(iq)); } + + + template<typename Identifier> + inline value_type derivative(const int& iq) const + { + return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, Term>::type()); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::true_) const + { + return -super::term.derivative<Identifier>(iq) * sin(super::term(iq)); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::false_) const + { + value_type result; + nullify(result); + return result; + } + }; + + /// + template<typename Term> + struct Sin : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + int degree; + + Sin(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} + + int getDegree() const + { + return degree * (super::term.getDegree()); + } + + inline value_type operator()(const int& iq) const { return sin(super::term(iq)); } + + + template<typename Identifier> + inline value_type derivative(const int& iq) const + { + return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, Term>::type()); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::true_) const + { + return super::term.derivative<Identifier>(iq) * cos(super::term(iq)); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::false_) const + { + value_type result; + nullify(result); + return result; + } + }; + + /// + template<typename Term> + struct Tan : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + int degree; + + Tan(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} + + int getDegree() const + { + return degree * (super::term.getDegree()); + } + + inline value_type operator()(const int& iq) const { return tan(super::term(iq)); } + + + template<typename Identifier> + inline value_type derivative(const int& iq) const + { + return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, Term>::type()); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::true_) const + { + return super::term.derivative<Identifier>(iq) * (1.0 - sqr(tan(super::term(iq)))); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::false_) const + { + value_type result; + nullify(result); + return result; + } + }; + + // ___________________________________________________________________________ + + + /// + template<typename Term> + struct Acos : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + int degree; + + Acos(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} + + int getDegree() const + { + return degree * (super::term.getDegree()); + } + + inline value_type operator()(const int& iq) const { return acos(super::term(iq)); } + + + template<typename Identifier> + inline value_type derivative(const int& iq) const + { + return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, Term>::type()); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::true_) const + { + return -super::term.derivative<Identifier>(iq) / (1.0 - sqr(super::term(iq))); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::false_) const + { + value_type result; + nullify(result); + return result; + } + }; + + /// + template<typename Term> + struct Asin : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + int degree; + + Asin(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} + + int getDegree() const + { + return degree * (super::term.getDegree()); + } + + inline value_type operator()(const int& iq) const { return asin(super::term(iq)); } + + + template<typename Identifier> + inline value_type derivative(const int& iq) const + { + return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, Term>::type()); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::true_) const + { + return super::term.derivative<Identifier>(iq) / sqrt(1.0 - sqr(super::term(iq))); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::false_) const + { + value_type result; + nullify(result); + return result; + } + }; + + /// + template<typename Term> + struct Atan : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + int degree; + + Atan(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} + + int getDegree() const + { + return degree * (super::term.getDegree()); + } + + inline value_type operator()(const int& iq) const { return atan(super::term(iq)); } + + + template<typename Identifier> + inline value_type derivative(const int& iq) const + { + return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, Term>::type()); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::true_) const + { + return super::term.derivative<Identifier>(iq) / (1.0 + sqr(super::term(iq))); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::false_) const + { + value_type result; + nullify(result); + return result; + } + }; + + /// + template<typename Term1, typename Term2> + struct Atan2 : public LazyOperatorTerm2<Term1, Term2> + { + typedef LazyOperatorTerm2<Term1, Term2> super; + typedef typename Term1::value_type value_type; + int degree; + + Atan2(const Term1& term1_, const Term2& term2_, int degree_ = 1) : super(term1_, term2_), degree(degree_) {} + + int getDegree() const + { + return degree * (super::term1.getDegree() + super::term2.getDegree()); + } + + inline value_type operator()(const int& iq) const { return atan2(super::term1(iq), super::term2(iq)); } + + + template<typename Identifier> + inline value_type derivative(const int& iq) const + { + throw std::runtime_error("diff(atanh2) not implemented yet!"); + value_type result; nullify(result); + return result; + } + }; + + // ___________________________________________________________________________ + + + /// + template<typename Term> + struct Cosh : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + int degree; + + Cosh(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} + + int getDegree() const + { + return degree * (super::term.getDegree()); + } + + inline value_type operator()(const int& iq) const { return cosh(super::term(iq)); } + + + template<typename Identifier> + inline value_type derivative(const int& iq) const + { + return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, Term>::type()); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::true_) const + { + return super::term.derivative<Identifier>(iq) * sinh(super::term(iq)); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::false_) const + { + value_type result; + nullify(result); + return result; + } + }; + + /// + template<typename Term> + struct Sinh : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + int degree; + + Sinh(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} + + int getDegree() const + { + return degree * (super::term.getDegree()); + } + + inline value_type operator()(const int& iq) const { return sinh(super::term(iq)); } + + + template<typename Identifier> + inline value_type derivative(const int& iq) const + { + return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, Term>::type()); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::true_) const + { + return super::term.derivative<Identifier>(iq) * cosh(super::term(iq)); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::false_) const + { + value_type result; + nullify(result); + return result; + } + }; + + /// + template<typename Term> + struct Tanh : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + int degree; + + Tanh(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} + + int getDegree() const + { + return degree * (super::term.getDegree()); + } + + inline value_type operator()(const int& iq) const { return tanh(super::term(iq)); } + + + template<typename Identifier> + inline value_type derivative(const int& iq) const + { + return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, Term>::type()); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::true_) const + { + return super::term.derivative<Identifier>(iq) * (1.0 - sqr(tanh(super::term(iq)))); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::false_) const + { + value_type result; + nullify(result); + return result; + } + }; + + // ___________________________________________________________________________ + + + /// + template<typename Term> + struct Acosh : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + int degree; + + Acosh(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} + + int getDegree() const + { + return degree * (super::term.getDegree()); + } + + inline value_type operator()(const int& iq) const { + value_type tmp = super::term(iq); + return log(tmp + sqrt(sqr(tmp) - 1.0)); + } + + + template<typename Identifier> + inline value_type derivative(const int& iq) const + { + throw std::runtime_error("diff(acosh) not implemented yet!"); + value_type result; nullify(result); + return result; + } + }; + + /// + template<typename Term> + struct Asinh : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + int degree; + + Asinh(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} + + int getDegree() const + { + return degree * (super::term.getDegree()); + } + + inline value_type operator()(const int& iq) const { + value_type tmp = super::term(iq); + return log(tmp + sqrt(sqr(tmp) + 1.0)); + } + + + template<typename Identifier> + inline value_type derivative(const int& iq) const + { + throw std::runtime_error("diff(asinh) not implemented yet!"); + value_type result; nullify(result); + return result; + } + }; + + /// + template<typename Term> + struct Atanh : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + int degree; + + Atanh(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} + + int getDegree() const + { + return degree * (super::term.getDegree()); + } + + inline value_type operator()(const int& iq) const { + value_type tmp = super::term(iq); + return 0.5 * log((1.0 + tmp) / (1.0 - tmp)); + } + + + template<typename Identifier> + inline value_type derivative(const int& iq) const + { + throw std::runtime_error("diff(atanh) not implemented yet!"); + value_type result; nullify(result); + return result; + } + }; + + + // ___________________________________________________________________________ + + + /// + template<typename Term1, typename Term2> + struct Max : public LazyOperatorTerm2<Term1, Term2> + { + typedef LazyOperatorTerm2<Term1, Term2> super; + typedef typename Term1::value_type value_type; + + Max(const Term1& term1_, const Term2& term2_) + : super(term1_, term2_) {} + + int getDegree() const + { + return std::max(super::term1.getDegree(), super::term2.getDegree()); + } + + inline value_type operator()(const int& iq) const + { + return std::max(super::term1(iq), super::term2(iq)); + } + + template<typename Identifier> + inline value_type derivative(const int& iq) const + { + return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, super>::type()); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::true_) const + { + return super::term1(iq) > super::term2(iq) ? super::term1.derivative<Identifier>(iq) : super::term2.derivative<Identifier>(iq); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::false_) const + { + value_type result; + nullify(result); + return result; + } + }; + + + /// + template<typename Term1, typename Term2> + struct Min : public LazyOperatorTerm2<Term1, Term2> + { + typedef LazyOperatorTerm2<Term1, Term2> super; + typedef typename Term1::value_type value_type; + + Min(const Term1& term1_, const Term2& term2_) + : super(term1_, term2_) {} + + int getDegree() const + { + return std::max(super::term1.getDegree(), super::term2.getDegree()); + } + + inline value_type operator()(const int& iq) const + { + return std::min(super::term1(iq), super::term2(iq)); + } + + template<typename Identifier> + inline value_type derivative(const int& iq) const + { + return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, super>::type()); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::true_) const + { + return super::term1(iq) < super::term2(iq) ? super::term1.derivative<Identifier>(iq) : super::term2.derivative<Identifier>(iq); + } + + template<typename Identifier> + inline value_type derivative(const int& iq, boost::mpl::false_) const + { + value_type result; + nullify(result); + return result; + } + }; + +} + + +namespace traits +{ + + template<typename Identifier, typename Term> + struct DependsOn<Identifier, AMDiS::result_of::Abs<Term> > + : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; + + template<typename Identifier, typename Term> + struct DependsOn<Identifier, AMDiS::result_of::Signum<Term> > + : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; + + template<typename Identifier, typename Term> + struct DependsOn<Identifier, AMDiS::result_of::Ceil<Term> > + : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; + + template<typename Identifier, typename Term> + struct DependsOn<Identifier, AMDiS::result_of::Floor<Term> > + : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; + + + template<typename Identifier, int I, typename Term> + struct DependsOn<Identifier, AMDiS::result_of::Pow<I, Term> > + : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; + + template<typename Identifier, typename Term> + struct DependsOn<Identifier, AMDiS::result_of::Sqrt<Term> > + : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; + + + template<typename Identifier, typename Term> + struct DependsOn<Identifier, AMDiS::result_of::Exp<Term> > + : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; + + template<typename Identifier, typename Term> + struct DependsOn<Identifier, AMDiS::result_of::Log<Term> > + : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; + + + template<typename Identifier, typename Term> + struct DependsOn<Identifier, AMDiS::result_of::Cos<Term> > + : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; + + template<typename Identifier, typename Term> + struct DependsOn<Identifier, AMDiS::result_of::Sin<Term> > + : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; + + template<typename Identifier, typename Term> + struct DependsOn<Identifier, AMDiS::result_of::Tan<Term> > + : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; + + + template<typename Identifier, typename Term> + struct DependsOn<Identifier, AMDiS::result_of::Acos<Term> > + : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; + + template<typename Identifier, typename Term> + struct DependsOn<Identifier, AMDiS::result_of::Asin<Term> > + : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; + + template<typename Identifier, typename Term> + struct DependsOn<Identifier, AMDiS::result_of::Atan<Term> > + : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; + + + template<typename Identifier, typename Term> + struct DependsOn<Identifier, AMDiS::result_of::Cosh<Term> > + : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; + + template<typename Identifier, typename Term> + struct DependsOn<Identifier, AMDiS::result_of::Sinh<Term> > + : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; + + template<typename Identifier, typename Term> + struct DependsOn<Identifier, AMDiS::result_of::Tanh<Term> > + : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; + + + template<typename Identifier, typename Term> + struct DependsOn<Identifier, AMDiS::result_of::Acosh<Term> > + : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; + + template<typename Identifier, typename Term> + struct DependsOn<Identifier, AMDiS::result_of::Asinh<Term> > + : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; + + template<typename Identifier, typename Term> + struct DependsOn<Identifier, AMDiS::result_of::Atanh<Term> > + : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; + + + template<typename Identifier, typename Term1, typename Term2> + struct DependsOn<Identifier, AMDiS::result_of::Max<Term1, Term2> > + : public DependsOn<Identifier, LazyOperatorTerm2<Term1, Term2> >::type {}; + + template<typename Identifier, typename Term1, typename Term2> + struct DependsOn<Identifier, AMDiS::result_of::Min<Term1, Term2> > + : public DependsOn<Identifier, LazyOperatorTerm2<Term1, Term2> >::type {}; + +} + + +// maximum of two terms +template<typename Term1, typename Term2> +inline typename boost::enable_if< + typename boost::mpl::and_<typename boost::is_base_of<LazyOperatorTermBase, Term1>::type, + typename boost::is_base_of<LazyOperatorTermBase, Term2>::type>::type, + result_of::Max<Term1, Term2> >::type +max(const Term1& t1, const Term2& t2) { return result_of::Max<Term1, Term2>(t1, t2); } + +template<typename T, typename Term> +inline typename boost::enable_if< + typename boost::mpl::and_<typename boost::is_fundamental<T>::type, + typename boost::is_base_of<LazyOperatorTermBase, Term>::type>::type, + result_of::Max<result_of::Const<T>, Term> >::type +max(const T& t1, const Term& t2) { return result_of::Max<result_of::Const<T>, Term>(constant(t1), t2); } + +template<typename Term, typename T> +inline typename boost::enable_if< + typename boost::mpl::and_<typename boost::is_fundamental<T>::type, + typename boost::is_base_of<LazyOperatorTermBase, Term>::type>::type, + result_of::Max<Term, result_of::Const<T> > >::type +max(const Term& t1, const T& t2) { return result_of::Max<Term, result_of::Const<T> >(t1, constant(t2)); } + + + +// minimum of two terms +template<typename Term1, typename Term2> +inline typename boost::enable_if< + typename boost::mpl::and_<typename boost::is_base_of<LazyOperatorTermBase, Term1>::type, + typename boost::is_base_of<LazyOperatorTermBase, Term2>::type>::type, + result_of::Min<Term1, Term2> >::type +min(const Term1& t1, const Term2& t2) { return result_of::Min<Term1, Term2>(t1, t2); } + +template<typename T, typename Term> +inline typename boost::enable_if< + typename boost::mpl::and_<typename boost::is_fundamental<T>::type, + typename boost::is_base_of<LazyOperatorTermBase, Term>::type>::type, + result_of::Min<result_of::Const<T>, Term> >::type +min(const T& t1, const Term& t2) { return result_of::Max<result_of::Const<T>, Term>(constant(t1), t2); } + +template<typename Term, typename T> +inline typename boost::enable_if< + typename boost::mpl::and_<typename boost::is_fundamental<T>::type, + typename boost::is_base_of<LazyOperatorTermBase, Term>::type>::type, + result_of::Min<Term, result_of::Const<T> > >::type +min(const Term& t1, const T& t2) { return result_of::Min<Term, result_of::Const<T> >(t1, constant(t2)); } + +//______________________________________________________________________________ + +// absolute value of a term +template<typename Term> +inline typename boost::enable_if< + typename boost::is_base_of<LazyOperatorTermBase, Term>::type, + result_of::Abs<Term> >::type +abs_(const Term& t) { return result_of::Abs<Term>(t); } // TODO: Funktionsnamen ohne Unterstrich + +// signum of a term +template<typename Term> +inline typename boost::enable_if< + typename boost::is_base_of<LazyOperatorTermBase, Term>::type, + result_of::Signum<Term> >::type +signum(const Term& t) { return result_of::Signum<Term>(t); } + +// +template<typename Term> +inline typename boost::enable_if< + typename boost::is_base_of<LazyOperatorTermBase, Term>::type, + result_of::Ceil<Term> >::type +ceil(const Term& t) { return result_of::Ceil<Term>(t); } + +// +template<typename Term> +inline typename boost::enable_if< + typename boost::is_base_of<LazyOperatorTermBase, Term>::type, + result_of::Floor<Term> >::type +floor(const Term& t) { return result_of::Floor<Term>(t); } + +//______________________________________________________________________________ + +// I'th power of a term +template<int I, typename Term> +inline typename boost::enable_if< + typename boost::is_base_of<LazyOperatorTermBase, Term>::type, + result_of::Pow<I, Term> >::type +pow(const Term& t) { return result_of::Pow<I, Term>(t); } + +// square root of a term +template<typename Term> +inline typename boost::enable_if< + typename boost::is_base_of<LazyOperatorTermBase, Term>::type, + result_of::Sqrt<Term> >::type +sqrt(const Term& t) { return result_of::Sqrt<Term>(t); } + +//______________________________________________________________________________ + +// exponential function of a term +template<typename Term> +inline typename boost::enable_if< + typename boost::is_base_of<LazyOperatorTermBase, Term>::type, + result_of::Exp<Term> >::type +exp(const Term& t) { return result_of::Exp<Term>(t); } + +// natural logarithm of a term +template<typename Term> +inline typename boost::enable_if< + typename boost::is_base_of<LazyOperatorTermBase, Term>::type, + result_of::Log<Term> >::type +log(const Term& t) { return result_of::Log<Term>(t); } + +//______________________________________________________________________________ + +// cosine function of a term +template<typename Term> +inline typename boost::enable_if< + typename boost::is_base_of<LazyOperatorTermBase, Term>::type, + result_of::Cos<Term> >::type +cos(const Term& t) { return result_of::Cos<Term>(t); } + +// sine function of a term +template<typename Term> +inline typename boost::enable_if< + typename boost::is_base_of<LazyOperatorTermBase, Term>::type, + result_of::Sin<Term> >::type +sin(const Term& t) { return result_of::Sin<Term>(t); } + +// tangens function of a term +template<typename Term> +inline typename boost::enable_if< + typename boost::is_base_of<LazyOperatorTermBase, Term>::type, + result_of::Tan<Term> >::type +tan(const Term& t) { return result_of::Tan<Term>(t); } + +//______________________________________________________________________________ + +// arkuscosine function of a term +template<typename Term> +inline typename boost::enable_if< + typename boost::is_base_of<LazyOperatorTermBase, Term>::type, + result_of::Acos<Term> >::type +acos(const Term& t) { return result_of::Acos<Term>(t); } + +// arkussine function of a term +template<typename Term> +inline typename boost::enable_if< + typename boost::is_base_of<LazyOperatorTermBase, Term>::type, + result_of::Asin<Term> >::type +asin(const Term& t) { return result_of::Asin<Term>(t); } + +// arkustangens function of a term +template<typename Term> +inline typename boost::enable_if< + typename boost::is_base_of<LazyOperatorTermBase, Term>::type, + result_of::Atan<Term> >::type +atan(const Term& t) { return result_of::Atan<Term>(t); } + +//______________________________________________________________________________ + +// cosine-hyperbolicus function of a term +template<typename Term> +inline typename boost::enable_if< + typename boost::is_base_of<LazyOperatorTermBase, Term>::type, + result_of::Cosh<Term> >::type +cosh(const Term& t) { return result_of::Cosh<Term>(t); } + +// sine-hyperbolicus function of a term +template<typename Term> +inline typename boost::enable_if< + typename boost::is_base_of<LazyOperatorTermBase, Term>::type, + result_of::Sin<Term> >::type +sinh(const Term& t) { return result_of::Sinh<Term>(t); } + +// tangens-hyperbolicus function of a term +template<typename Term> +inline typename boost::enable_if< + typename boost::is_base_of<LazyOperatorTermBase, Term>::type, + result_of::Tan<Term> >::type +tanh(const Term& t) { return result_of::Tanh<Term>(t); } + +//______________________________________________________________________________ + +// arkuscosine-hypüerbolicus function of a term +template<typename Term> +inline typename boost::enable_if< + typename boost::is_base_of<LazyOperatorTermBase, Term>::type, + result_of::Acosh<Term> >::type +acosh(const Term& t) { return result_of::Acosh<Term>(t); } + +// arkussine-hyperbolicus function of a term +template<typename Term> +inline typename boost::enable_if< + typename boost::is_base_of<LazyOperatorTermBase, Term>::type, + result_of::Asinh<Term> >::type +asinh(const Term& t) { return result_of::Asinh<Term>(t); } + +// arkustangens-hyperbolicus function of a term +template<typename Term> +inline typename boost::enable_if< + typename boost::is_base_of<LazyOperatorTermBase, Term>::type, + result_of::Atanh<Term> >::type +atanh(const Term& t) { return result_of::Atanh<Term>(t); } + +} // end namespace AMDiS + +#endif \ No newline at end of file diff --git a/AMDiS/src/io/Reader.h b/AMDiS/src/io/Reader.h index a29691dc57002de35cd18048a1e45b736c734f20..41ed8d9174bdca7e81a2fadbea96841d8d42c79f 100644 --- a/AMDiS/src/io/Reader.h +++ b/AMDiS/src/io/Reader.h @@ -32,6 +32,7 @@ #include "Arh2Reader.h" #include "MacroReader.h" #include "ValueReader.h" +#include "XYZReader.h" #ifdef HAVE_PNG #include "PngReader.h" diff --git a/AMDiS/src/io/XYZReader.cc b/AMDiS/src/io/XYZReader.cc new file mode 100644 index 0000000000000000000000000000000000000000..eda0d358a96460499520aa5c87c6d6121954218f --- /dev/null +++ b/AMDiS/src/io/XYZReader.cc @@ -0,0 +1,100 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + +#include <cstring> +#include <fstream> +#include <vector> + +#include "ValueReader.h" +#include "MacroInfo.h" +#include "detail/VtkReader.h" + +namespace AMDiS { namespace io { + + namespace XYZReader + { + using namespace std; + + /** \brief + * Copies the values of a value file to a DOF vector. + * + * The DOF vector must have been created by a corresponding mesh file. The + * information about this file and the macro triangulation are stored in + * macroFileInfo. The function now reads the corresponding value file and + * copies the values to the correct positions in the DOF vector. + */ + void readFile(std::string filename, + std::pair<std::vector<WorldVector<double> >, + std::vector<std::vector<double> > > &data) + { + FUNCNAME("readFile()"); + using ::AMDiS::io::VtkReader::detail::string2valueList; + + TEST_EXIT(filename != "")("Filename not specified!\n"); + + string line; + + // open the file and read the data to the vector values. + ifstream file(filename.c_str(), ios_base::in); + getline(file, line); + int numRows = boost::lexical_cast<int>(line); + if (numRows == 0 || file.eof()) + return; + + getline(file, line); // comments + + TEST_EXIT(!file.eof())("Not enough values stored in file!\n"); + getline(file, line); // first line + vector<double> values_tmp; + string2valueList(line, values_tmp); + + int numValues = values_tmp.size() - 1 - 3; // 1st value=nr, 2-4th value=coordinates + + int nr; + WorldVector<double> p; + vector<double> values(numValues); + double tmp; + for (int i = 0; i < Global::getGeo(WORLD); i++) + p[i] = values_tmp[i+1]; + for (int i = 0; i < numValues; i++) + values[i] = values_tmp[i+4]; + data.first.push_back(p); + data.second.push_back(values); + + while (!file.eof()) { + file >> nr; + for (int i = 0; i < Global::getGeo(WORLD); i++) + file >> p[i]; + for (int i = Global::getGeo(WORLD); i < 3; i++) + file >> tmp; + for (int i = 0; i < numValues; i++) + file >> values[i]; + if (!file.good()) + break; + data.first.push_back(p); + data.second.push_back(values); + } + + file.close(); + } + + } // end namespace XYZReader +} } // end namespace io, AMDiS diff --git a/AMDiS/src/io/XYZReader.h b/AMDiS/src/io/XYZReader.h new file mode 100644 index 0000000000000000000000000000000000000000..9cdedd87845be5eb230512ac21e3a4ec198a89c5 --- /dev/null +++ b/AMDiS/src/io/XYZReader.h @@ -0,0 +1,53 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + + +/** \file XYZReader.h */ + +#ifndef AMDIS_XYZREADER_H +#define AMDIS_XYZREADER_H + +#include <cstring> + +namespace AMDiS { namespace io { + + /** \ingroup Input + * + * \brief + * Namespace of methods which read a XYZ-file + */ + namespace XYZReader + { + template<typename Container> + void readFile(std::string filename, Container& data) + { + ERROR_EXIT("Can not read xyz-file to given container!\n"); + } + + /// Copies the values of a value file to a DOF vector. + void readFile(std::string filename, + std::pair<std::vector<WorldVector<double> >, + std::vector<std::vector<double> > > &data); + + } // end namespace XYZReader +} } // end namespace io, AMDiS + +#endif