All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Angle.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 #include "tools/Angle.h"
25 
26 #include <string>
27 #include <cmath>
28 
29 using namespace std;
30 
31 namespace PLMD{
32 namespace colvar{
33 
34 //+PLUMEDOC COLVAR ANGLE
35 /*
36 Calculate an angle.
37 
38 This command can be used to compute the angle between three atoms. Alternatively
39 if four atoms appear in the atom
40 specification it calculates the angle between
41 two vectors identified by two pairs of atoms.
42 
43 If _three_ atoms are given, the angle is defined as:
44 \f[
45 \theta=\arccos\left(\frac{ {\bf r}_{21}\cdot {\bf r}_{23}}{
46 |{\bf r}_{21}| |{\bf r}_{23}|}\right)
47 \f]
48 Here \f$ {\bf r}_{ij}\f$ is the distance vector among the
49 i-th and the j-th listed atom.
50 
51 If _four_ atoms are given, the angle is defined as:
52 \f[
53 \theta=\arccos\left(\frac{ {\bf r}_{21}\cdot {\bf r}_{34}}{
54 |{\bf r}_{21}| |{\bf r}_{34}|}\right)
55 \f]
56 
57 Notice that angles defined in this way are non-periodic variables and
58 their value is limited by definition between 0 and \f$\pi\f$.
59 
60 The vectors \f$ {\bf r}_{ij}\f$ are by default evaluated taking
61 periodic boundary conditions into account.
62 This behavior can be changed with the NOPBC flag.
63 
64 \par Examples
65 
66 This command tells plumed to calculate the angle between the vector connecting atom 1 to atom 2 and
67 the vector connecting atom 2 to atom 3 and to print it on file COLVAR1. At the same time,
68 the angle between vector connecting atom 1 to atom 2 and the vector connecting atom 3 to atom 4 is printed
69 on file COLVAR2.
70 \verbatim
71 
72 a: ANGLE ATOMS=1,2,3
73 # equivalently one could state:
74 # a: ANGLE ATOMS=1,2,2,3
75 
76 b: ANGLE ATOMS=1,2,3,4
77 
78 PRINT ARG=a FILE=COLVAR1
79 PRINT ARG=b FILE=COLVAR2
80 \endverbatim
81 (see also \ref PRINT)
82 
83 
84 */
85 //+ENDPLUMEDOC
86 
87 class Angle : public Colvar {
88  bool pbc;
89 
90 public:
91  Angle(const ActionOptions&);
92 // active methods:
93  virtual void calculate();
94  static void registerKeywords( Keywords& keys );
95 };
96 
97 PLUMED_REGISTER_ACTION(Angle,"ANGLE")
98 
99 void Angle::registerKeywords( Keywords& keys ){
100  Colvar::registerKeywords(keys);
101  keys.add("atoms","ATOMS","the list of atoms involved in this collective variable (either 3 or 4 atoms)");
102 }
103 
104 Angle::Angle(const ActionOptions&ao):
106 pbc(true)
107 {
108  vector<AtomNumber> atoms;
109  parseAtomList("ATOMS",atoms);
110  bool nopbc=!pbc;
111  parseFlag("NOPBC",nopbc);
112  pbc=!nopbc;
113 
114  if(atoms.size()==3){
115  log.printf(" between atoms %d %d %d\n",atoms[0].serial(),atoms[1].serial(),atoms[2].serial());
116  atoms.resize(4);
117  atoms[3]=atoms[2];
118  atoms[2]=atoms[1];
119  }else if(atoms.size()==4){
120  log.printf(" between lines %d-%d and %d-%d\n",atoms[0].serial(),atoms[1].serial(),atoms[2].serial(),atoms[3].serial());
121  }else error("Number of specified atoms should be either 3 or 4");
122 
123  if(pbc) log.printf(" using periodic boundary conditions\n");
124  else log.printf(" without periodic boundary conditions\n");
125 
127  requestAtoms(atoms);
128  checkRead();
129 }
130 
131 // calculator
133 
134  Vector dij,dik;
135  if(pbc){
138  } else {
139  dij=delta(getPosition(2),getPosition(3));
140  dik=delta(getPosition(1),getPosition(0));
141  }
142  Vector ddij,ddik;
143  PLMD::Angle a;
144  double angle=a.compute(dij,dik,ddij,ddik);
145  setAtomsDerivatives(0,ddik);
146  setAtomsDerivatives(1,-ddik);
147  setAtomsDerivatives(2,-ddij);
148  setAtomsDerivatives(3,ddij);
149  setValue (angle);
150  setBoxDerivatives (-(Tensor(dij,ddij)+Tensor(dik,ddik)));
151 }
152 
153 }
154 }
155 
156 
157 
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 compute(const Vector &v1, const Vector &v2) const
Compute the angle between vectors v1 and v2.
Definition: Angle.cpp:28
Class implementing fixed size vectors of doubles.
Definition: Vector.h:74
void setAtomsDerivatives(int, const Vector &)
Definition: Colvar.h:97
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.
void requestAtoms(const std::vector< AtomNumber > &a)
Definition: Colvar.cpp:44
Class to compute angles.
Definition: Angle.h:39
#define PLUMED_COLVAR_INIT(ao)
Definition: Colvar.h:29
void setBoxDerivatives(const Tensor &)
Definition: Colvar.h:102
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
virtual void calculate()
Calculate an Action.
Definition: Angle.cpp:132
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)
Provides the keyword ANGLE
Definition: Angle.cpp:87
Vector pbcDistance(const Vector &, const Vector &) const
Compute the pbc distance between two positions.
Tensor3d Tensor
Definition: Tensor.h:425
void const char const char int double * a
Definition: Matrix.h:42