/* * 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 Set { // 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 typename Set::iterator iterator; typedef typename Set::const_iterator const_iterator; AtomSetMixin() : Set() {} AtomSetMixin(const Set& src) : Set(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; 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 (atom::*_f)() const,T startValue) : f(_f), value(startValue) {} T operator+(atom *atom){ return value + (atom->*f)(); } T operator=(T _value){ value = _value; return value; } T (atom::*f)() const; T value; }; template struct stepValueSum { stepValueSum(unsigned int _step, T (atom::*_f)(unsigned int) const,T startValue) : step(_step), f(_f), value(startValue) {} T operator+(atom *atom){ return value + (atom->*f)(step); } T operator=(T _value){ value = _value; return value; } unsigned int step; T (atom::*f)(unsigned int) const; T value; }; }; template inline void AtomSetMixin::translate(const Vector &translater){ BOOST_FOREACH(atom *atom,*this){ *(atom) += translater; } } template inline void AtomSetMixin::addVelocityAtStep(const Vector velocity, unsigned int step){ BOOST_FOREACH(atom *atom,*this){ atom->Trajectory.U.at(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(&atom::getMass,0)).value; } template inline double AtomSetMixin::totalTemperatureAtStep(unsigned int step) const{ return accumulate(this->begin(),this->end(),stepValueSum(step,&atom::getKineticEnergy,0)).value; } template inline Vector AtomSetMixin::totalMomentumAtStep(unsigned int step) const{ return accumulate(this->begin(),this->end(),stepValueSum(step,&atom::getMomentum,Vector())).value; } // allows simpler definition of AtomSets #define ATOMSET(container_type) AtomSetMixin > #endif /* ATOMSET_HPP_ */