/* * AtomSet.hpp * * Created on: Jul 30, 2010 * Author: crueger */ #ifndef ATOMSET_HPP_ #define ATOMSET_HPP_ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include /** * A simple mixin to give any STL conforming structure fast Vector abilities * * TODO: make this work for maps */ #include "atom.hpp" // this tests, whether we actually have a Vector template struct is_atom{}; template <> struct is_atom{ typedef void wrong_type; }; template class AtomSetMixin : public container_type { // when our set carries something besides a atom* this will produce an error typedef typename is_atom::wrong_type check_for_atom; public: // typedefs for STL conforming structure typedef iterator_type iterator; typedef const_iterator_type const_iterator; AtomSetMixin() : container_type() {} AtomSetMixin(const container_type& src) : container_type(src) {} virtual ~AtomSetMixin(){} /** * translate all Atoms within this set by a specified amount */ void translate(const Vector &translater); void addVelocityAtStep(const Vector velocity, unsigned int step); template void transformNodes(Function f); double totalMass() const; double totalTemperatureAtStep(unsigned int step) const; Vector totalMomentumAtStep(unsigned int step) const; size_t getMaxTrajectorySize() const; private: template struct workOnNodePointer { workOnNodePointer(Function &_f) : f(_f){} void operator()(atom *atom){ atom->setPosition(f(atom->getPosition())); } Function &f; }; template struct valueSum { valueSum(T (AtomInfo::*_f)() const,T startValue) : f(_f), value(startValue) {} T operator+(AtomInfo *atom){ return value + (atom->*f)(); } T operator=(T _value){ value = _value; return value; } T (AtomInfo::*f)() const; T value; }; template struct valueMax { valueMax(T (AtomInfo::*_f)() const,T startValue) : f(_f), value(startValue) {} T operator+(AtomInfo *atom){ const T temp = (atom->*f)(); return value < temp ? temp : value; } T operator=(T _value){ value = _value; return value; } T (AtomInfo::*f)() const; T value; }; template struct stepValueSum { stepValueSum(unsigned int _step, T (AtomInfo::*_f)(unsigned int) const,T startValue) : step(_step), f(_f), value(startValue) {} T operator+(AtomInfo *atom){ return value + (atom->*f)(step); } T operator=(T _value){ value = _value; return value; } unsigned int step; T (AtomInfo::*f)(unsigned int) const; T value; }; }; template inline void AtomSetMixin::translate(const Vector &translater){ BOOST_FOREACH(AtomInfo *atom,*this){ *(atom) += translater; } } template inline void AtomSetMixin::addVelocityAtStep(const Vector velocity, unsigned int step){ BOOST_FOREACH(AtomInfo *atom,*this){ atom->setAtomicVelocityAtStep(step, atom->getAtomicVelocityAtStep(step)+velocity); } } template template inline void AtomSetMixin::transformNodes(Function f){ std::for_each(this->begin(), this->end(), AtomSetMixin::workOnNodePointer(f)); } template inline double AtomSetMixin::totalMass() const{ return accumulate(this->begin(),this->end(),valueSum(&AtomInfo::getMass,0)).value; } template inline size_t AtomSetMixin::getMaxTrajectorySize() const { return accumulate(this->begin(),this->end(),valueMax(&AtomInfo::getTrajectorySize,(size_t)1)).value; } template inline double AtomSetMixin::totalTemperatureAtStep(unsigned int step) const{ return accumulate(this->begin(),this->end(),stepValueSum(step,&AtomInfo::getKineticEnergy,0)).value; } template inline Vector AtomSetMixin::totalMomentumAtStep(unsigned int step) const{ return accumulate(this->begin(),this->end(),stepValueSum(step,&AtomInfo::getMomentum,Vector())).value; } // allows simpler definition of AtomSets #define ATOMSET(container_type) AtomSetMixin > #endif /* ATOMSET_HPP_ */