source: src/Atom/AtomSet.hpp@ 91c409

Candidate_v1.7.0 stable
Last change on this file since 91c409 was d40189, checked in by Frederik Heber <frederik.heber@…>, 5 years ago

OutputTemperature -> OutputEnergies, SaveTemperature -> SaveEnergies.

  • added force and momentum calculation.
  • TESTS: adapted test.ekin test file and integration/MolecularDynamics tests.
  • DOCU: Adapted userguide for changed action.
  • Property mode set to 100644
File size: 8.2 KB
Line 
1/*
2 * AtomSet.hpp
3 *
4 * Created on: Jul 30, 2010
5 * Author: crueger
6 */
7
8#ifndef ATOMSET_HPP_
9#define ATOMSET_HPP_
10
11// include config.h
12#ifdef HAVE_CONFIG_H
13#include <config.h>
14#endif
15
16
17
18#include <algorithm>
19#include <functional>
20#include <limits>
21#include <numeric>
22
23#include <boost/bind.hpp>
24#include <boost/foreach.hpp>
25
26/**
27 * A simple mixin to give any STL conforming structure fast Vector abilities
28 *
29 * TODO: make this work for maps
30 */
31
32#include "atom.hpp"
33
34// this tests, whether we actually have a Vector
35template <class V>
36struct is_atom{};
37
38template <>
39struct is_atom<atom*>{
40 typedef void wrong_type;
41};
42
43template <>
44struct is_atom<const atom*>{
45 typedef void wrong_type;
46};
47
48template <class container_type,
49 class iterator_type = typename container_type::iterator,
50 class const_iterator_type = typename container_type::const_iterator>
51class AtomSetMixin : public container_type
52{
53 // when our set carries something besides a atom* this will produce an error
54 typedef typename is_atom<typename container_type::value_type>::wrong_type check_for_atom;
55public:
56 // typedefs for STL conforming structure
57 typedef iterator_type iterator;
58 typedef const_iterator_type const_iterator;
59
60 AtomSetMixin() :
61 container_type()
62 {}
63
64 AtomSetMixin(const container_type& src) :
65 container_type(src)
66 {}
67 virtual ~AtomSetMixin(){}
68
69 /**
70 * translate all Atoms within this set by a specified amount
71 */
72 void translate(const Vector &translater);
73 void addVelocityAtStep(const Vector velocity, unsigned int step);
74
75 template<class Function>
76 void transformNodes(Function f);
77 double totalMass() const;
78 double totalTemperatureAtStep(unsigned int step) const;
79 Vector totalForceAtStep(unsigned int step) const;
80 Vector totalMomentumAtStep(unsigned int step) const;
81 Vector totalAbsoluteMomentumAtStep(unsigned int step) const;
82 Vector totalAbsoluteForceAtStep(unsigned int step) const;
83
84 size_t getMaxTrajectorySize() const;
85
86 void sortByIds();
87
88private:
89 template<class Function>
90 struct workOnNodePointer {
91 workOnNodePointer(Function &_f) : f(_f){}
92 void operator()(atom *atom){
93 atom->setPosition(f(atom->getPosition()));
94 }
95 Function &f;
96 };
97
98 template<class T>
99 struct valueSum {
100 valueSum(T (AtomInfo::*_f)() const,T startValue) :
101 f(_f),
102 value(startValue)
103 {}
104 T operator+(const AtomInfo *atom){
105 return value + (atom->*f)();
106 }
107 T operator=(T _value){
108 value = _value;
109 return value;
110 }
111 T (AtomInfo::*f)() const;
112 T value;
113 };
114
115 template<class T>
116 struct absValueSum {
117 absValueSum(T (AtomInfo::*_f)() const,T startValue) :
118 f(_f),
119 value(startValue)
120 {}
121 T operator+(const AtomInfo *atom){
122 temp = (atom->*f)();
123 for (int i=0;i<NDIM;++i)
124 temp[i] = fabs(temp[i]);
125 return value + temp;
126 }
127 T operator=(T _value){
128 value = _value;
129 for (int i=0;i<NDIM;++i)
130 value[i] = fabs(value[i]);
131 return value;
132 }
133 T (AtomInfo::*f)() const;
134 T value;
135 T temp;
136 };
137
138 template<class T>
139 struct valueMax {
140 valueMax(T (AtomInfo::*_f)() const,T startValue) :
141 f(_f),
142 value(startValue)
143 {}
144 T operator+(const AtomInfo *atom){
145 const T temp = (atom->*f)();
146 return value < temp ? temp : value;
147 }
148 T operator=(T _value){
149 value = _value;
150 return value;
151 }
152 T (AtomInfo::*f)() const;
153 T value;
154 };
155
156 template<class T>
157 struct stepValueSum {
158 stepValueSum(unsigned int _step, T (AtomInfo::*_f)(unsigned int) const,T startValue) :
159 step(_step),
160 f(_f),
161 value(startValue)
162 {}
163 T operator+(const AtomInfo *atom){
164 return value + (atom->*f)(step);
165 }
166 T operator=(T _value){
167 value = _value;
168 return value;
169 }
170 unsigned int step;
171 T (AtomInfo::*f)(unsigned int) const;
172 T value;
173 };
174
175 template<class T>
176 struct stepAbsValueSum {
177 stepAbsValueSum(unsigned int _step, T (AtomInfo::*_f)(unsigned int) const,T startValue) :
178 step(_step),
179 f(_f),
180 value(startValue)
181 {}
182 T operator+(const AtomInfo *atom){
183 temp = (atom->*f)(step);
184 for (int i=0;i<NDIM;++i)
185 temp[i] = fabs(temp[i]);
186 return value + temp;
187 }
188 T operator=(T _value){
189 value = _value;
190 for (int i=0;i<NDIM;++i)
191 value[i] = fabs(value[i]);
192 return value;
193 }
194 unsigned int step;
195 T (AtomInfo::*f)(unsigned int) const;
196 T value;
197 T temp;
198 };
199};
200
201template <class container_type,
202 class iterator_type,
203 class const_iterator_type>
204inline void AtomSetMixin<container_type,iterator_type,const_iterator_type>::translate(const Vector &translater){
205 BOOST_FOREACH(AtomInfo *atom,*this){
206 *(atom) += translater;
207 }
208}
209
210template <class container_type,
211 class iterator_type,
212 class const_iterator_type>
213inline void AtomSetMixin<container_type,iterator_type,const_iterator_type>::addVelocityAtStep(const Vector velocity, unsigned int step){
214 BOOST_FOREACH(AtomInfo *atom,*this){
215 atom->setAtomicVelocityAtStep(step, atom->getAtomicVelocityAtStep(step)+velocity);
216 }
217}
218
219template <class container_type,
220 class iterator_type,
221 class const_iterator_type>
222template<class Function>
223inline void AtomSetMixin<container_type,iterator_type,const_iterator_type>::transformNodes(Function f){
224 std::for_each(this->begin(),
225 this->end(),
226 AtomSetMixin::workOnNodePointer<Function>(f));
227}
228
229template <class container_type,
230 class iterator_type,
231 class const_iterator_type>
232inline double AtomSetMixin<container_type,iterator_type,const_iterator_type>::totalMass() const{
233 return accumulate(this->begin(),this->end(),valueSum<double>(&AtomInfo::getMass,0)).value;
234}
235
236template <class container_type,
237 class iterator_type,
238 class const_iterator_type>
239inline size_t AtomSetMixin<container_type,iterator_type,const_iterator_type>::getMaxTrajectorySize() const
240{
241 return accumulate(this->begin(),this->end(),valueMax<size_t>(&AtomInfo::getTrajectorySize,(size_t)1)).value;
242}
243
244template <class container_type,
245 class iterator_type,
246 class const_iterator_type>
247inline double AtomSetMixin<container_type,iterator_type,const_iterator_type>::totalTemperatureAtStep(unsigned int step) const{
248 return accumulate(this->begin(),this->end(),stepValueSum<double>(step,&AtomInfo::getKineticEnergy,0)).value;
249}
250
251template <class container_type,
252 class iterator_type,
253 class const_iterator_type>
254inline Vector AtomSetMixin<container_type,iterator_type,const_iterator_type>::totalMomentumAtStep(unsigned int step) const{
255 return accumulate(this->begin(),this->end(),stepValueSum<Vector>(step,&AtomInfo::getMomentum,Vector())).value;
256}
257
258template <class container_type,
259 class iterator_type,
260 class const_iterator_type>
261inline Vector AtomSetMixin<container_type,iterator_type,const_iterator_type>::totalAbsoluteMomentumAtStep(unsigned int step) const{
262 return accumulate(this->begin(),this->end(),stepAbsValueSum<Vector>(step,&AtomInfo::getMomentum,Vector())).value;
263}
264
265template <class container_type,
266 class iterator_type,
267 class const_iterator_type>
268inline Vector AtomSetMixin<container_type,iterator_type,const_iterator_type>::totalForceAtStep(unsigned int step) const{
269 return accumulate(this->begin(),this->end(),stepValueSum<Vector>(step,&AtomInfo::getAcceleration,Vector())).value;
270}
271
272template <class container_type,
273 class iterator_type,
274 class const_iterator_type>
275inline Vector AtomSetMixin<container_type,iterator_type,const_iterator_type>::totalAbsoluteForceAtStep(unsigned int step) const{
276 return accumulate(this->begin(),this->end(),stepAbsValueSum<Vector>(step,&AtomInfo::getAcceleration,Vector())).value;
277}
278
279template <class container_type,
280 class iterator_type,
281 class const_iterator_type>
282inline void AtomSetMixin<container_type,iterator_type,const_iterator_type>::sortByIds(){
283 std::sort(this->begin(), this->end(),
284 boost::bind(std::less<atomId_t>(),
285 boost::bind(&atom::getId, _1),
286 boost::bind(&atom::getId, _2)));
287}
288
289// allows simpler definition of AtomSets
290#define ATOMSET(container_type) AtomSetMixin<container_type<atom*> >
291#define CONSTATOMSET(container_type) AtomSetMixin<container_type<const atom*> >
292
293#endif /* ATOMSET_HPP_ */
Note: See TracBrowser for help on using the repository browser.