All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Torsion.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/Torsion.h"
25 
26 #include <string>
27 #include <cmath>
28 
29 using namespace std;
30 
31 namespace PLMD{
32 namespace colvar{
33 
34 //+PLUMEDOC COLVAR TORSION
35 /*
36 Calculate a torsional angle.
37 
38 This command can be used to compute the torsion between four atoms or alternatively
39 to calculate the angle between two vectors projected on the plane
40 orthogonal to an axis.
41 
42 \par Examples
43 
44 This input tells plumed to print the torsional angle between atoms 1, 2, 3 and 4
45 on file COLVAR.
46 \verbatim
47 t: TORSION ATOMS=1,2,3,4
48 # this is an alternative, equivalent, definition:
49 # t: TORSION VECTOR1=2,1 AXIS=2,3 VECTOR2=3,4
50 PRINT ARG=t FILE=COLVAR
51 \endverbatim
52 
53 */
54 //+ENDPLUMEDOC
55 
56 class Torsion : public Colvar {
57  bool pbc;
58  bool do_cosine;
59 
60 public:
61  Torsion(const ActionOptions&);
62 // active methods:
63  virtual void calculate();
64  static void registerKeywords(Keywords& keys);
65 };
66 
67 PLUMED_REGISTER_ACTION(Torsion,"TORSION")
68 
69 void Torsion::registerKeywords(Keywords& keys){
70  Colvar::registerKeywords( keys );
71  keys.add("atoms-1","ATOMS","the four atoms involved in the torsional angle");
72  keys.add("atoms-2","AXIS","two atoms that define an axis. You can use this to find the angle in the plane perpendicular to the axis between the vectors specified using the VECTOR1 and VECTOR2 keywords.");
73  keys.add("atoms-2","VECTOR1","two atoms that define a vector. You can use this in combination with VECTOR2 and AXIS");
74  keys.add("atoms-2","VECTOR2","two atoms that define a vector. You can use this in combination with VECTOR1 and AXIS");
75  keys.addFlag("COSINE",false,"calculate cosine instead of dihedral");
76 }
77 
78 Torsion::Torsion(const ActionOptions&ao):
80 pbc(true),
81 do_cosine(false)
82 {
83  vector<AtomNumber> atoms,v1,v2,axis;
84  parseAtomList("ATOMS",atoms);
85  parseAtomList("VECTOR1",v1);
86  parseAtomList("VECTOR2",v2);
87  parseAtomList("AXIS",axis);
88 
89  parseFlag("COSINE",do_cosine);
90 
91  bool nopbc=!pbc;
92  parseFlag("NOPBC",nopbc);
93  pbc=!nopbc;
94  checkRead();
95 
96  if(atoms.size()==4){
97  if(!(v1.empty()) && (v2.empty()) && (axis.empty()))
98  error("ATOMS keyword is not compatible with VECTOR1, VECTOR2 and AXIS keywords");
99  log.printf(" between atoms %d %d %d %d\n",atoms[0].serial(),atoms[1].serial(),atoms[2].serial(),atoms[3].serial());
100  atoms.resize(6);
101  atoms[5]=atoms[3];
102  atoms[4]=atoms[2];
103  atoms[3]=atoms[2];
104  atoms[2]=atoms[1];
105  }else if(atoms.empty()){
106  if(!(v1.size()==2 && v2.size()==2 && axis.size()==2))
107  error("VECTOR1, VECTOR2 and AXIS should specify 2 atoms each");
108  log.printf(" between lines %d-%d and %d-%d, projected on the plane orthogonal to line %d-%d\n",
109  v1[0].serial(),v1[1].serial(),v2[0].serial(),v2[1].serial(),axis[0].serial(),axis[1].serial());
110  atoms.resize(6);
111  atoms[0]=v1[1];
112  atoms[1]=v1[0];
113  atoms[2]=axis[0];
114  atoms[3]=axis[1];
115  atoms[4]=v2[0];
116  atoms[5]=v2[1];
117  }else error("ATOMS should specify 4 atoms");
118 
119  if(pbc) log.printf(" using periodic boundary conditions\n");
120  else log.printf(" without periodic boundary conditions\n");
121 
122  if(do_cosine) log.printf(" calculating cosine instead of torsion\n");
123 
125  if(!do_cosine) setPeriodic("-pi","pi");
126  else setNotPeriodic();
127  requestAtoms(atoms);
128 }
129 
130 // calculator
132 
133  Vector d0,d1,d2;
134  if(pbc){
138  } else {
139  d0=delta(getPosition(1),getPosition(0));
140  d1=delta(getPosition(3),getPosition(2));
141  d2=delta(getPosition(5),getPosition(4));
142  }
143  Vector dd0,dd1,dd2;
144  PLMD::Torsion t;
145  double torsion=t.compute(d0,d1,d2,dd0,dd1,dd2);
146  if(do_cosine){
147  dd0 *= -sin(torsion);
148  dd1 *= -sin(torsion);
149  dd2 *= -sin(torsion);
150  torsion = cos(torsion);
151  }
152  setAtomsDerivatives(0,dd0);
153  setAtomsDerivatives(1,-dd0);
154  setAtomsDerivatives(2,dd1);
155  setAtomsDerivatives(3,-dd1);
156  setAtomsDerivatives(4,dd2);
157  setAtomsDerivatives(5,-dd2);
158 
159  setValue (torsion);
160  setBoxDerivatives (-(extProduct(d0,dd0)+extProduct(d1,dd1)+extProduct(d2,dd2)));
161 }
162 
163 }
164 }
165 
166 
167 
Class to compute torsional angles.
Definition: Torsion.h:39
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 Vector &v3) const
Compute the angle between the projections of v1 and v3 on the plane orthogonal to v2...
Definition: Torsion.cpp:30
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
Provides the keyword TORSION
Definition: Torsion.cpp:56
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
#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
void setPeriodic(const std::string &min, const std::string &max)
Set the value to be periodic with a particular domain.
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)
TensorGeneric< n, m > extProduct(const VectorGeneric< n > &v1, const VectorGeneric< m > &v2)
Definition: Tensor.h:396
Vector pbcDistance(const Vector &, const Vector &) const
Compute the pbc distance between two positions.
virtual void calculate()
Calculate an Action.
Definition: Torsion.cpp:131