All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Distance.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 "Colvar.h"
23 #include "ActionRegister.h"
24 
25 #include <string>
26 #include <cmath>
27 
28 using namespace std;
29 
30 namespace PLMD{
31 namespace colvar{
32 
33 //+PLUMEDOC COLVAR DISTANCE
34 /*
35 Calculate the distance between a pair of atoms.
36 By default the distance is computed taking into account periodic
37 boundary conditions. This behavior can be changed with the NOPBC flag.
38 Moreover, single components (x,y, and z) can be also computed.
39 
40 Notice that single components will not have the proper periodicity!
41 A possible hack is shown in one of the examples below.
42 
43 \par Examples
44 
45 The following input tells plumed to print the distance between atoms 3 and 5,
46 the distance between atoms 2 and 4 and the x component of the distance between atoms 2 and 4.
47 \verbatim
48 d1: DISTANCE ATOMS=3,5
49 d2: DISTANCE ATOMS=2,4
50 d2c: DISTANCE ATOMS=2,4 COMPONENTS
51 PRINT ARG=d1,d2,d2c.x
52 \endverbatim
53 (See also \ref PRINT).
54 
55 The following input computes the end-to-end distance for a polymer
56 of 100 atoms and keeps it at a value around 5.
57 \verbatim
58 WHOLEMOLECULES ENTITY0=1-100
59 e2e: DISTANCE ATOMS=1,100 NOPBC
60 RESTRAINT ARG=e2e KAPPA=1 AT=5
61 \endverbatim
62 (See also \ref WHOLEMOLECULES and \ref RESTRAINT).
63 
64 Notice that NOPBC is used
65 to be sure that if the end-to-end distance is larger than half the simulation
66 box the distance is compute properly. Also notice that, since many MD
67 codes break molecules across cell boundary, it might be necessary to
68 use the \ref WHOLEMOLECULES keyword (also notice that it should be
69 _before_ distance). The list of atoms provided to WHOLEMOLECULES
70 here contains all the atoms between 1 and 100. Strictly speaking, this
71 is not necessary. If you know for sure that atoms with difference in
72 the index say equal to 10 are _not_ going to be farther than half cell
73 you can e.g. use
74 \verbatim
75 WHOLEMOLECULES ENTITY0=1,10,20,30,40,50,60,70,80,90,100
76 e2e: DISTANCE ATOMS=1,100 NOPBC
77 RESTRAINT ARG=e2e KAPPA=1 AT=5
78 \endverbatim
79 Just be sure that the ordered list provide to WHOLEMOLECULES has the following
80 properties:
81 - Consecutive atoms should be closer than half-cell throughout the entire simulation.
82 - Atoms required later for the distance (e.g. 1 and 100) should be included in the list
83 
84 The following example shows how to take into account periodicity e.g.
85 in z-component of a distance
86 \verbatim
87 # this is a center of mass of a large group
88 c: COM ATOMS=1-100
89 # this is the distance between atom 101 and the group
90 d: DISTANCE ATOMS=c,101 COMPONENTS
91 # this makes a new variable, dd, equal to d and periodic, with domain -10,10
92 # this is the right choise if e.g. the cell is orthorombic and its size in
93 # z direction is 20.
94 dz: COMBINE ARG=d.z PERIODIC=-10,10
95 # metadynamics on dd
96 METAD ARG=dz SIGMA=0.1 HEIGHT=0.1 PACE=200
97 \endverbatim
98 (see also \ref COM, \ref COMBINE, and \ref METAD)
99 
100 
101 
102 
103 */
104 //+ENDPLUMEDOC
105 
106 class Distance : public Colvar {
108  bool pbc;
109 
110 public:
111  static void registerKeywords( Keywords& keys );
112  Distance(const ActionOptions&);
113 // active methods:
114  virtual void calculate();
115 };
116 
117 PLUMED_REGISTER_ACTION(Distance,"DISTANCE")
118 
119 void Distance::registerKeywords( Keywords& keys ){
120  Colvar::registerKeywords( keys );
121  keys.add("atoms","ATOMS","the pair of atom that we are calculating the distance between");
122  keys.addFlag("COMPONENTS",false,"calculate the x, y and z components of the distance separately and store them as label.x, label.y and label.z");
123  keys.addOutputComponent("x","COMPONENTS","the x-component of the vector connecting the two atoms");
124  keys.addOutputComponent("y","COMPONENTS","the y-component of the vector connecting the two atoms");
125  keys.addOutputComponent("z","COMPONENTS","the z-component of the vector connecting the two atoms");
126 }
127 
128 Distance::Distance(const ActionOptions&ao):
130 components(false),
131 pbc(true)
132 {
133  vector<AtomNumber> atoms;
134  parseAtomList("ATOMS",atoms);
135  if(atoms.size()!=2)
136  error("Number of specified atoms should be 2");
137  parseFlag("COMPONENTS",components);
138  bool nopbc=!pbc;
139  parseFlag("NOPBC",nopbc);
140  pbc=!nopbc;
141  checkRead();
142 
143  log.printf(" between atoms %d %d\n",atoms[0].serial(),atoms[1].serial());
144  if(pbc) log.printf(" using periodic boundary conditions\n");
145  else log.printf(" without periodic boundary conditions\n");
146 
147 
148  if(!components){
149 
151 
152  } else{
156  log<<" WARNING: components will not have the proper periodicity - see manual\n";
157  }
158 
159  requestAtoms(atoms);
160 }
161 
162 
163 // calculator
165 
166  Vector distance;
167  if(pbc){
168  distance=pbcDistance(getPosition(0),getPosition(1));
169  } else {
170  distance=delta(getPosition(0),getPosition(1));
171  }
172  const double value=distance.modulo();
173  const double invvalue=1.0/value;
174 
175  if(!components){
176 
177  setAtomsDerivatives(0,-invvalue*distance);
178  setAtomsDerivatives(1,invvalue*distance);
179  setBoxDerivatives (-invvalue*Tensor(distance,distance));
180  setValue (value);
181 
182  }else{
183 
184  Value* valuex=getPntrToComponent("x");
185  Value* valuey=getPntrToComponent("y");
186  Value* valuez=getPntrToComponent("z");
187 
188  setAtomsDerivatives (valuex,0,Vector(-1,0,0));
189  setAtomsDerivatives (valuex,1,Vector(+1,0,0));
190  setBoxDerivatives (valuex,Tensor(distance,Vector(-1,0,0)));
191  valuex->set(distance[0]);
192 
193  setAtomsDerivatives (valuey,0,Vector(0,-1,0));
194  setAtomsDerivatives (valuey,1,Vector(0,+1,0));
195  setBoxDerivatives (valuey,Tensor(distance,Vector(0,-1,0)));
196  valuey->set(distance[1]);
197 
198  setAtomsDerivatives (valuez,0,Vector(0,0,-1));
199  setAtomsDerivatives (valuez,1,Vector(0,0,+1));
200  setBoxDerivatives (valuez,Tensor(distance,Vector(0,0,-1)));
201  valuez->set(distance[2]);
202  };
203 }
204 
205 }
206 }
207 
208 
209 
const Vector & getPosition(int) const
Get position of i-th atom.
void parseFlag(const std::string &key, bool &t)
Parse one keyword as boolean flag.
Definition: Action.cpp:104
void setNotPeriodic()
Set your default value to have no periodicity.
Log & log
Reference to the log stream.
Definition: Action.h:93
double modulo() const
Compute the modulo.
Definition: Vector.h:325
void componentIsNotPeriodic(const std::string &name)
Set your value component to have no periodicity.
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
void setAtomsDerivatives(int, const Vector &)
Definition: Colvar.h:97
Provides the keyword DISTANCE
Definition: Distance.cpp:106
void error(const std::string &msg) const
Crash calculation and print documentation.
Definition: Action.cpp:195
void checkRead()
Check if Action was properly read.
Definition: Action.cpp:161
STL namespace.
void parseAtomList(const std::string &key, std::vector< AtomNumber > &t)
Parse a list of atoms without a numbered keyword.
void addValueWithDerivatives()
Add a value with the name label that has derivatives.
virtual void calculate()
Calculate an Action.
Definition: Distance.cpp:164
void requestAtoms(const std::vector< AtomNumber > &a)
Definition: Colvar.cpp:44
#define PLUMED_COLVAR_INIT(ao)
Definition: Colvar.h:29
void setBoxDerivatives(const Tensor &)
Definition: Colvar.h:102
void set(double)
Set the value of the function.
Definition: Value.h:174
This class holds the keywords and their documentation.
Definition: Keywords.h:36
This class is used to bring the relevant information to the Action constructor.
Definition: Action.h:41
int printf(const char *fmt,...)
Formatted output with explicit format - a la printf.
Definition: OFile.cpp:82
This is the abstract base class to use for implementing new collective variables, within it there is ...
Definition: Colvar.h:39
VectorGeneric< n > delta(const VectorGeneric< n > &v1, const VectorGeneric< n > &v2)
Definition: Vector.h:262
void setValue(const double &d)
Set the default value (the one without name)
Vector pbcDistance(const Vector &, const Vector &) const
Compute the pbc distance between two positions.
void addComponentWithDerivatives(const std::string &name)
Add a value with a name like label.name that has derivatives.
Value * getPntrToComponent(int i)
Return a pointer to the component by index.
Tensor3d Tensor
Definition: Tensor.h:425
Vector3d Vector
Alias for three dimensional vectors.
Definition: Vector.h:351