All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
ActionAtomistic.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 "ActionAtomistic.h"
23 #include "PlumedMain.h"
24 #include "ActionSet.h"
25 #include <vector>
26 #include <string>
27 #include "ActionWithValue.h"
28 #include "Colvar.h"
29 #include "ActionWithVirtualAtom.h"
30 #include "tools/Exception.h"
31 #include "Atoms.h"
32 #include "tools/Pbc.h"
33 #include "tools/PDB.h"
34 
35 using namespace std;
36 using namespace PLMD;
37 
38 ActionAtomistic::~ActionAtomistic(){
39 // forget the pending request
40  atoms.remove(this);
41  delete(&pbc);
42 }
43 
44 ActionAtomistic::ActionAtomistic(const ActionOptions&ao):
45 Action(ao),
46 pbc(*new(Pbc)),
47 lockRequestAtoms(false),
48 atoms(plumed.getAtoms())
49 {
50  atoms.add(this);
51  if(atoms.getNatoms()==0) error("Cannot perform calculations involving atoms without atoms");
52 }
53 
55  (void) keys; // avoid warning
56 }
57 
58 
59 void ActionAtomistic::requestAtoms(const vector<AtomNumber> & a){
60  plumed_massert(!lockRequestAtoms,"requested atom list can only be changed in the prepare() method");
61  int nat=a.size();
62  indexes=a;
63  positions.resize(nat);
64  forces.resize(nat);
65  masses.resize(nat);
66  charges.resize(nat);
67  int n=atoms.positions.size();
69  unique.clear();
70  for(unsigned i=0;i<indexes.size();i++){
71  plumed_massert(indexes[i].index()<n,"atom out of range");
73 // only real atoms are requested to lower level Atoms class
74  else unique.insert(indexes[i]);
75  }
76 
77 }
78 
80  return pbc.distance(v1,v2);
81 }
82 
85 }
86 
88  if(!a){
89  a=dynamic_cast<ActionWithValue*>(this);
90  plumed_massert(a,"only Actions with a value can be differentiated");
91  }
92 
93  const int nval=a->getNumberOfComponents();
94  const int natoms=getNumberOfAtoms();
95  std::vector<Vector> value(nval*natoms);
96  std::vector<Tensor> valuebox(nval);
97  std::vector<Vector> savedPositions(natoms);
98  const double delta=sqrt(epsilon);
99 
100  for(int i=0;i<natoms;i++) for(int k=0;k<3;k++){
101  savedPositions[i][k]=positions[i][k];
102  positions[i][k]=positions[i][k]+delta;
103  a->calculate();
104  positions[i][k]=savedPositions[i][k];
105  for(unsigned j=0;j<nval;j++){
106  value[j*natoms+i][k]=a->getOutputQuantity(j);
107  }
108  }
109  for(int i=0;i<3;i++) for(int k=0;k<3;k++){
110  double arg0=box(i,k);
111  for(int j=0;j<natoms;j++) positions[j]=pbc.realToScaled(positions[j]);
112  box(i,k)=box(i,k)+delta;
113  pbc.setBox(box);
114  for(int j=0;j<natoms;j++) positions[j]=pbc.scaledToReal(positions[j]);
115  a->calculate();
116  box(i,k)=arg0;
117  pbc.setBox(box);
118  for(int j=0;j<natoms;j++) positions[j]=savedPositions[j];
119  for(unsigned j=0;j<nval;j++) valuebox[j](i,k)=a->getOutputQuantity(j);
120  }
121 
122  a->calculate();
123  a->clearDerivatives();
124  for(unsigned j=0;j<nval;j++){
125  Value* v=a->copyOutput(j);
126  double ref=v->get();
127  if(v->hasDerivatives()){
128  for(int i=0;i<natoms;i++) for(int k=0;k<3;k++) {
129  double d=(value[j*natoms+i][k]-ref)/delta;
130  v->addDerivative(startnum+3*i+k,d);
131  }
132  Tensor virial;
133  for(int i=0;i<3;i++) for(int k=0;k<3;k++)virial(i,k)= (valuebox[j](i,k)-ref)/delta;
134 // BE CAREFUL WITH NON ORTHOROMBIC CELL
135  virial=-matmul(box.transpose(),virial);
136  for(int i=0;i<3;i++) for(int k=0;k<3;k++) v->addDerivative(startnum+3*natoms+3*k+i,virial(k,i));
137  }
138  }
139 }
140 
141 void ActionAtomistic::parseAtomList(const std::string&key, std::vector<AtomNumber> &t){
142  parseAtomList(key,-1,t);
143 }
144 
145 void ActionAtomistic::parseAtomList(const std::string&key,const int num, std::vector<AtomNumber> &t){
146  plumed_massert( keywords.style(key,"atoms"), "keyword " + key + " should be registered as atoms");
147  vector<string> strings;
148  if( num<0 ){
149  parseVector(key,strings);
150  if(strings.empty()) return;
151  } else {
152  if ( !parseNumberedVector(key,num,strings) ) return;
153  }
154 
155  Tools::interpretRanges(strings); t.resize(0);
156  for(unsigned i=0;i<strings.size();++i){
157  bool ok=false;
158  AtomNumber atom;
159  ok=Tools::convert(strings[i],atom); // this is converting strings to AtomNumbers
160  if(ok) t.push_back(atom);
161 // here we check if the atom name is the name of a group
162  if(!ok){
163  if(atoms.groups.count(strings[i])){
164  map<string,vector<AtomNumber> >::const_iterator m=atoms.groups.find(strings[i]);
165  t.insert(t.end(),m->second.begin(),m->second.end());
166  ok=true;
167  }
168  }
169 // here we check if the atom name is the name of an added virtual atom
170  if(!ok){
171  const ActionSet&actionSet(plumed.getActionSet());
172  for(ActionSet::const_iterator a=actionSet.begin();a!=actionSet.end();++a){
173  ActionWithVirtualAtom* c=dynamic_cast<ActionWithVirtualAtom*>(*a);
174  if(c) if(c->getLabel()==strings[i]){
175  ok=true;
176  t.push_back(c->getIndex());
177  break;
178  }
179  }
180  }
181  plumed_massert(ok,"it was not possible to interpret atom name " + strings[i]);
182  }
183 }
184 
185 
187  box=atoms.box;
188  pbc=atoms.pbc;
190  const vector<Vector> & p(atoms.positions);
191  const vector<double> & c(atoms.charges);
192  const vector<double> & m(atoms.masses);
193  for(unsigned j=0;j<indexes.size();j++) positions[j]=p[indexes[j].index()];
194  for(unsigned j=0;j<indexes.size();j++) charges[j]=c[indexes[j].index()];
195  for(unsigned j=0;j<indexes.size();j++) masses[j]=m[indexes[j].index()];
196  Colvar*cc=dynamic_cast<Colvar*>(this);
197  if(cc && cc->checkIsEnergy()) energy=atoms.getEnergy();
198 }
199 
200 void ActionAtomistic::setForcesOnAtoms( const std::vector<double>& forcesToApply, unsigned ind ){
201  for(unsigned i=0;i<indexes.size();++i){
202  forces[i][0]=forcesToApply[ind]; ind++;
203  forces[i][1]=forcesToApply[ind]; ind++;
204  forces[i][2]=forcesToApply[ind]; ind++;
205  }
206  virial(0,0)=forcesToApply[ind]; ind++;
207  virial(0,1)=forcesToApply[ind]; ind++;
208  virial(0,2)=forcesToApply[ind]; ind++;
209  virial(1,0)=forcesToApply[ind]; ind++;
210  virial(1,1)=forcesToApply[ind]; ind++;
211  virial(1,2)=forcesToApply[ind]; ind++;
212  virial(2,0)=forcesToApply[ind]; ind++;
213  virial(2,1)=forcesToApply[ind]; ind++;
214  virial(2,2)=forcesToApply[ind]; ind++;
215  plumed_dbg_assert( ind==forcesToApply.size() );
216 }
217 
219  vector<Vector> & f(atoms.forces);
220  Tensor & v(atoms.virial);
221  for(unsigned j=0;j<indexes.size();j++) f[indexes[j].index()]+=forces[j];
222  v+=virial;
224 }
225 
227  Colvar*cc=dynamic_cast<Colvar*>(this);
228  if(cc && cc->checkIsEnergy()) error("can't read energies from pdb files");
229 
230  for(unsigned j=0;j<indexes.size();j++){
231  if( indexes[j].index()>pdb.size() ) error("there are not enough atoms in the input pdb file");
232  if( pdb.getAtomNumbers()[j].index()!=indexes[j].index() ) error("there are atoms missing in the pdb file");
233  positions[j]=pdb.getPositions()[indexes[j].index()];
234  }
235  for(unsigned j=0;j<indexes.size();j++) charges[j]=pdb.getBeta()[indexes[j].index()];
236  for(unsigned j=0;j<indexes.size();j++) masses[j]=pdb.getOccupancy()[indexes[j].index()];
237 }
double forceOnEnergy
Definition: Atoms.h:90
Simple class to store the index of an atom.
Definition: AtomNumber.h:39
const int & getNatoms() const
Definition: Atoms.h:201
std::vector< Vector > forces
Definition: Atoms.h:51
std::vector< double > charges
Definition: Atoms.h:53
static void registerKeywords(Keywords &keys)
const double epsilon
TensorGeneric< m, n > transpose() const
return the transpose matrix
Definition: Tensor.h:325
std::vector containing the sequence of Action to be done.
Definition: ActionSet.h:38
double get() const
Get the value of the function.
Definition: Value.h:186
Class implementing fixed size matrices of doubles.
Definition: Tensor.h:70
void add(const ActionAtomistic *)
Definition: Atoms.cpp:261
TensorGeneric< n, l > matmul(const TensorGeneric< n, m > &a, const TensorGeneric< m, l > &b)
Definition: Tensor.h:343
Class implementing fixed size vectors of doubles.
Definition: Vector.h:74
A class for holding the value of a function together with its derivatives.
Definition: Value.h:46
std::vector< double > masses
Definition: Atoms.h:52
static bool convert(const std::string &str, double &t)
Convert a string to a double, reading it.
Definition: Tools.cpp:74
Vector scaledToReal(const Vector &) const
Transform a vector in scaled coordinates to a vector in real space.
Definition: Pbc.cpp:206
void error(const std::string &msg) const
Crash calculation and print documentation.
Definition: Action.cpp:195
const std::string & getLabel() const
Returns the label.
Definition: Action.h:263
STL namespace.
std::set< AtomNumber > unique
void parseAtomList(const std::string &key, std::vector< AtomNumber > &t)
Parse a list of atoms without a numbered keyword.
virtual void calculate()=0
Calculate an Action.
virtual void calculateNumericalDerivatives(ActionWithValue *a=NULL)
N.B.
std::vector< Vector > positions
Definition: Atoms.h:50
void const char const char int * n
Definition: Matrix.h:42
Definition: Pbc.h:38
void addDependency(Action *)
Specify that this Action depends on another one.
Definition: Action.cpp:123
Vector distance(const Vector &, const Vector &, int *nshifts) const
internal version of distance, also returns the number of attempted shifts (used in Pbc::test())...
Definition: Pbc.cpp:158
Used to create a PLMD::Action that has some scalar or vectorial output that may or may not have some ...
const std::vector< Vector > & getPositions() const
Access to the position array.
Definition: PDB.cpp:31
This class holds the keywords and their documentation.
Definition: Keywords.h:36
const std::vector< double > & getBeta() const
Access to the beta array.
Definition: PDB.cpp:39
bool chargesWereSet() const
Definition: Atoms.h:221
This class is used to bring the relevant information to the Action constructor.
Definition: Action.h:41
std::vector< Vector > positions
This is the abstract base class to use for implementing new collective variables, within it there is ...
Definition: Colvar.h:39
void readAtomsFromPDB(const PDB &pdb)
Read in an input file containing atom positions and calculate the action for the atomic configuration...
Base class for all the input Actions.
Definition: Action.h:60
const std::vector< double > & getOccupancy() const
Access to the occupancy array.
Definition: PDB.cpp:35
Value * copyOutput(const std::string &name) const
Return a pointer to the value with name (this is used to retrieve values in other PLMD::Actions) You ...
double getEnergy() const
Definition: Atoms.h:172
void parseVector(const std::string &key, std::vector< T > &t)
Parse one keyword as std::vector.
Definition: Action.h:311
Inherit from here if you are calculating the position of a virtual atom (eg a center of mass) ...
VectorGeneric< n > delta(const VectorGeneric< n > &v1, const VectorGeneric< n > &v2)
Definition: Vector.h:262
static void interpretRanges(std::vector< std::string > &)
Interpret atom ranges.
Definition: Tools.cpp:231
bool style(const std::string &k, const std::string &t) const
Check if the keyword with name k has style t.
Definition: Keywords.cpp:223
Minimalistic pdb parser.
Definition: PDB.h:38
double getOutputQuantity(const unsigned j) const
Get the value of one of the components of the PLMD::Action.
Tensor virial
Definition: Atoms.h:57
std::vector< AtomNumber > indexes
Tensor box
Definition: Atoms.h:55
AtomNumber getIndex() const
Return the atom id of the corresponding virtual atom.
void const char const char int double int double double int int double int * m
Definition: Matrix.h:42
Vector pbcDistance(const Vector &, const Vector &) const
Compute the pbc distance between two positions.
void calculateAtomicNumericalDerivatives(ActionWithValue *a, const unsigned &startnum)
Numerical derivative routine to use when using Actions that inherit from BOTH ActionWithArguments and...
bool parseNumberedVector(const std::string &key, const int no, std::vector< T > &t)
Parse a vector with a number.
Definition: Action.h:352
bool isVirtualAtom(AtomNumber) const
Definition: Atoms.h:206
virtual void clearDerivatives()
Clear the derivatives of values wrt parameters.
bool checkIsEnergy()
Definition: Colvar.h:68
void requestAtoms(const std::vector< AtomNumber > &a)
Request an array of atoms.
Main plumed object.
Definition: Plumed.h:201
int getNumberOfComponents() const
Returns the number of values defined.
void clearDependencies()
Clear the dependence list for this Action.
Definition: Action.cpp:153
ActionWithVirtualAtom * getVirtualAtomsAction(AtomNumber) const
Definition: Atoms.h:211
unsigned size() const
Returns the number of atoms.
Definition: PDB.cpp:72
const std::vector< AtomNumber > & getAtomNumbers() const
Access to the indexes.
Definition: PDB.cpp:47
void setForcesOnAtoms(const std::vector< double > &forcesToApply, unsigned ind=0)
Add the forces to the atoms.
unsigned getNumberOfAtoms() const
Get number of available atoms.
std::vector< double > charges
void const char const char int double * a
Definition: Matrix.h:42
Vector realToScaled(const Vector &) const
Transform a vector in real space to a vector in scaled coordinates.
Definition: Pbc.cpp:202
const Keywords & keywords
Definition: Action.h:161
void addDerivative(unsigned i, double d)
Add some derivative to the ith component of the derivatives array.
Definition: Value.h:224
std::vector< Vector > forces
std::vector< double > masses
void setBox(const Tensor &b)
Set the lattice vectors.
Definition: Pbc.cpp:115
bool hasDerivatives() const
Check whether or not this particular quantity has derivatives.
Definition: Value.h:213
std::map< std::string, std::vector< AtomNumber > > groups
Definition: Atoms.h:73
Pbc & pbc
Definition: Atoms.h:56