All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
MDAtoms.cpp
Go to the documentation of this file.
1 /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2  Copyright (c) 2013 The plumed team
3  (see the PEOPLE file at the root of the distribution for a list of names)
4 
5  See http://www.plumed-code.org for more information.
6 
7  This file is part of plumed, version 2.0.
8 
9  plumed is free software: you can redistribute it and/or modify
10  it under the terms of the GNU Lesser General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  (at your option) any later version.
13 
14  plumed is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public License
20  along with plumed. If not, see <http://www.gnu.org/licenses/>.
21 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
22 #include <algorithm>
23 #include <string>
24 #include "MDAtoms.h"
25 #include "tools/Tools.h"
26 #include "tools/Exception.h"
27 
28 using namespace std;
29 
30 namespace PLMD {
31 
32 /// Class containing the pointers to the MD data
33 /// It is templated so that single and double precision versions coexist
34 /// IT IS STILL UNDOCUMENTED. IT PROBABLY NEEDS A STRONG CLEANUP
35 template <class T>
37 public MDAtomsBase
38 {
39  double scalep,scalef;
40  double scaleb,scalev;
41  int stride;
42  T *m;
43  T *c;
44  T *px; T *py; T *pz;
45  T *fx; T *fy; T *fz;
46  T *box;
47  T *virial;
48 public:
49  MDAtomsTyped();
50  void setm(void*m);
51  void setc(void*m);
52  void setBox(void*);
53  void setp(void*p);
54  void setVirial(void*);
55  void setf(void*f);
56  void setp(void*p,int i);
57  void setf(void*f,int i);
58  void setUnits(const Units&,const Units&);
59  void MD2double(const void*m,double&d)const{
60  d=double(*(static_cast<const T*>(m)));
61  }
62  void double2MD(const double&d,void*m)const{
63  *(static_cast<T*>(m))=T(d);
64  }
65  void getBox(Tensor &)const;
66  void getPositions(const vector<int>&index,vector<Vector>&positions)const;
67  void getMasses(const vector<int>&index,vector<double>&)const;
68  void getCharges(const vector<int>&index,vector<double>&)const;
69  void updateVirial(const Tensor&)const;
70  void updateForces(const vector<int>&index,const vector<Vector>&);
71  void rescaleForces(const vector<int>&index,double factor);
72  unsigned getRealPrecision()const;
73 };
74 
75 template <class T>
76 void MDAtomsTyped<T>::setUnits(const Units& units,const Units& MDUnits){
77  double lscale=units.getLength()/MDUnits.getLength();
78  double escale=units.getEnergy()/MDUnits.getEnergy();
79 // scalep and scaleb are used to convert MD to plumed
80  scalep=1.0/lscale;
81  scaleb=1.0/lscale;
82 // scalef and scalev are used to convert plumed to MD
83  scalef=escale/lscale;
84  scalev=escale;
85 }
86 
87 template <class T>
89  if(this->box) for(int i=0;i<3;i++)for(int j=0;j<3;j++) box(i,j)=this->box[3*i+j]*scaleb;
90  else box.zero();
91 }
92 
93 template <class T>
94 void MDAtomsTyped<T>::getPositions(const vector<int>&index,vector<Vector>&positions)const{
95  for(unsigned i=0;i<index.size();++i){
96  positions[index[i]][0]=px[stride*i]*scalep;
97  positions[index[i]][1]=py[stride*i]*scalep;
98  positions[index[i]][2]=pz[stride*i]*scalep;
99  }
100 }
101 
102 template <class T>
103 void MDAtomsTyped<T>::getMasses(const vector<int>&index,vector<double>&masses)const{
104  if(m) for(unsigned i=0;i<index.size();++i) masses[index[i]]=m[i];
105  else for(unsigned i=0;i<index.size();++i) masses[index[i]]=0.0;
106 }
107 
108 template <class T>
109 void MDAtomsTyped<T>::getCharges(const vector<int>&index,vector<double>&charges)const{
110  if(c) for(unsigned i=0;i<index.size();++i) charges[index[i]]=c[i];
111  else for(unsigned i=0;i<index.size();++i) charges[index[i]]=0.0;
112 }
113 
114 template <class T>
115 void MDAtomsTyped<T>::updateVirial(const Tensor&virial)const{
116  if(this->virial) for(int i=0;i<3;i++)for(int j=0;j<3;j++) this->virial[3*i+j]+=T(virial(i,j)*scalev);
117 }
118 
119 template <class T>
120 void MDAtomsTyped<T>::updateForces(const vector<int>&index,const vector<Vector>&forces){
121  for(unsigned i=0;i<index.size();++i){
122  fx[stride*i]+=T(scalef*forces[index[i]][0]);
123  fy[stride*i]+=T(scalef*forces[index[i]][1]);
124  fz[stride*i]+=T(scalef*forces[index[i]][2]);
125  }
126 }
127 
128 template <class T>
129 void MDAtomsTyped<T>::rescaleForces(const vector<int>&index,double factor){
130  if(virial) for(unsigned i=0;i<3;i++)for(unsigned j=0;j<3;j++) virial[3*i+j]*=T(factor);
131  for(unsigned i=0;i<index.size();++i){
132  fx[stride*i]*=T(factor);
133  fy[stride*i]*=T(factor);
134  fz[stride*i]*=T(factor);
135  }
136 }
137 
138 template <class T>
140  return sizeof(T);
141 }
142 
143 template <class T>
144 void MDAtomsTyped<T>::setp(void*pp){
145  T*p=static_cast<T*>(pp);
146  plumed_assert(stride==0 || stride==3);
147  px=p;
148  py=p+1;
149  pz=p+2;
150  stride=3;
151 }
152 
153 template <class T>
155  box=static_cast<T*>(pp);
156 }
157 
158 
159 template <class T>
160 void MDAtomsTyped<T>::setf(void*ff){
161  T*f=static_cast<T*>(ff);
162  plumed_assert(stride==0 || stride==3);
163  fx=f;
164  fy=f+1;
165  fz=f+2;
166  stride=3;
167 }
168 
169 template <class T>
170 void MDAtomsTyped<T>::setp(void*pp,int i){
171  T*p=static_cast<T*>(pp);
172  plumed_assert(stride==0 || stride==1);
173  if(i==0)px=p;
174  if(i==1)py=p;
175  if(i==2)pz=p;
176  stride=1;
177 }
178 
179 template <class T>
181  virial=static_cast<T*>(pp);
182 }
183 
184 
185 template <class T>
186 void MDAtomsTyped<T>::setf(void*ff,int i){
187  T*f=static_cast<T*>(ff);
188  plumed_assert(stride==0 || stride==1);
189  if(i==0)fx=f;
190  if(i==1)fy=f;
191  if(i==2)fz=f;
192  stride=1;
193 }
194 
195 template <class T>
197  this->m=static_cast<T*>(m);
198 }
199 
200 template <class T>
202  this->c=static_cast<T*>(c);
203 }
204 
205 template <class T>
207  scalep(1.0),
208  scalef(1.0),
209  scaleb(1.0),
210  scalev(1.0),
211  stride(0),
212  m(NULL),
213  c(NULL),
214  px(NULL),
215  py(NULL),
216  pz(NULL),
217  fx(NULL),
218  fy(NULL),
219  fz(NULL),
220  box(NULL),
221  virial(NULL)
222 {}
223 
225  if(p==sizeof(double)){
226  return new MDAtomsTyped<double>;
227  } else if (p==sizeof(float)){
228  return new MDAtomsTyped<float>;
229  }
230  std::string pp;
231  Tools::convert(p,pp);
232  plumed_merror("cannot create an MD interface with sizeof(real)=="+ pp);
233  return NULL;
234 }
235 
236 }
237 
void zero()
set it to zero
Definition: Tensor.h:198
Class implementing fixed size matrices of doubles.
Definition: Tensor.h:70
static bool convert(const std::string &str, double &t)
Convert a string to a double, reading it.
Definition: Tools.cpp:74
STL namespace.
Class containing interface to MDAtomsTyped.
Definition: MDAtoms.h:48
Small utility class that contains information about units.
Definition: Units.h:41
const double & getEnergy() const
Get energy units as double.
Definition: Units.h:90
void double2MD(const double &d, void *m) const
Convert a double to a pointer to an MD-real.
Definition: MDAtoms.cpp:62
void const char const char int double int double double int int double int * m
Definition: Matrix.h:42
const double & getLength() const
Get length units as double.
Definition: Units.h:95
void MD2double(const void *m, double &d) const
Convert a pointer to an MD-real to a double.
Definition: MDAtoms.cpp:59
Class containing the pointers to the MD data It is templated so that single and double precision vers...
Definition: MDAtoms.cpp:36
static MDAtomsBase * create(unsigned n)
Creates an MDAtomsTyped object such that sizeof(T)==n.
Definition: MDAtoms.cpp:224