All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
MovingRestraint.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 "Bias.h"
23 #include "ActionRegister.h"
24 
25 
26 using namespace std;
27 
28 
29 namespace PLMD{
30 namespace bias{
31 
32 //+PLUMEDOC BIAS MOVINGRESTRAINT
33 /*
34 Add a time-dependent, harmonic restraint on one or more variables.
35 
36 This form of bias can be used to performed steered MD \cite Grubmuller3
37 and Jarzynski sampling \cite jarzynski.
38 
39 The harmonic restraint on your system is given by:
40 
41 \f[
42 V(\vec{s},t) = \frac{1}{2} \kappa(t) ( \vec{s} - \vec{s}_0(t) )^2
43 \f]
44 
45 The time dependence of \f$\kappa\f$ and \f$\vec{s}_0\f$ are specified by a list of
46 STEP, KAPPA and AT keywords. These keywords tell plumed what values \f$\kappa\f$ and \f$\vec{s}_0\f$
47 should have at the time specified by the corresponding STEP keyword. Inbetween these times
48 the values of \f$\kappa\f$ and \f$\vec{s}_0\f$ are linearly interpolated.
49 
50 \par Examples
51 The following input is dragging the distance between atoms 2 and 4
52 from 1 to 2 in the first 1000 steps, then back in the next 1000 steps.
53 In the following 500 steps the restraint is progressively switched off.
54 \verbatim
55 DISTANCE ATOMS=2,4 LABEL=d
56 MOVINGRESTRAINT ...
57  ARG=d
58  STEP0=0 AT0=1.0 KAPPA0=100.0
59  STEP1=1000 AT1=2.0
60  STEP2=2000 AT2=1.0
61  STEP3=2500 KAPPA3=0.0
62 ... MOVINGRESTRAINT
63 \endverbatim
64 The following input is progressively building restraints
65 distances between atoms 1 and 5 and between atoms 2 and 4
66 in the first 1000 steps. Afterwards, the restraint is kept
67 static.
68 \verbatim
69 DISTANCE ATOMS=1,5 LABEL=d1
70 DISTANCE ATOMS=2,4 LABEL=d2
71 MOVINGRESTRAINT ...
72  ARG=d1,d2
73  STEP0=0 AT0=1.0,1.5 KAPPA0=0.0,0.0
74  STEP1=1000 AT1=1.0,1.5 KAPPA1=1.0,1.0
75 ... MOVINGRESTRAINT
76 \endverbatim
77 The following input is progressively bringing atoms 1 and 2
78 close to each other with an upper wall
79 \verbatim
80 DISTANCE ATOMS=1,2 LABEL=d1
81 MOVINGRESTRAINT ...
82  ARG=d1
83  VERSE=U
84  STEP0=0 AT0=1.0 KAPPA0=10.0
85  STEP1=1000 AT1=0.0
86 ... MOVINGRESTRAINT
87 \endverbatim
88 
89 By default the Action is issuing some values which are
90 the work on each degree of freedom, the center of the harmonic potential,
91 the total bias deposited
92 
93 (See also \ref DISTANCE).
94 
95 \attention Work is not computed properly when KAPPA is time dependent.
96 
97 */
98 //+ENDPLUMEDOC
99 
100 
101 class MovingRestraint : public Bias{
102  std::vector<std::vector<double> > at;
103  std::vector<std::vector<double> > kappa;
104  std::vector<long int> step;
105  std::vector<double> oldaa;
106  std::vector<double> oldf;
107  std::vector<string> verse;
108  std::vector<double> work;
109 public:
111  void calculate();
112  static void registerKeywords( Keywords& keys );
113 };
114 
115 PLUMED_REGISTER_ACTION(MovingRestraint,"MOVINGRESTRAINT")
116 
117 void MovingRestraint::registerKeywords( Keywords& keys ){
118  Bias::registerKeywords(keys);
119  keys.use("ARG");
120  keys.add("compulsory","VERSE","B","Tells plumed whether the restraint is only acting for CV larger (U) or smaller (L) than the restraint or whether it is acting on both sides (B)");
121  keys.add("numbered","STEP","This keyword appears multiple times as STEPx with x=0,1,2,...,n. Each value given represents the MD step at which the restraint parameters take the values KAPPAx and ATx.");
122  keys.reset_style("STEP","compulsory");
123  keys.add("numbered","AT","ATx is equal to the position of the restraint at time STEPx. For intermediate times this parameter is linearly interpolated. If no ATx is specified for STEPx then the values of AT are kept constant during the interval of time between STEPx-1 and STEPx.");
124  keys.reset_style("AT","compulsory");
125  keys.add("numbered","KAPPA","KAPPAx is equal to the value of the force constants at time STEPx. For intermediate times this parameter is linearly interpolated. If no KAPPAx is specified for STEPx then the values of KAPPAx are kept constant during the interval of time between STEPx-1 and STEPx.");
126  keys.reset_style("KAPPA","compulsory");
127  componentsAreNotOptional(keys);
128  keys.addOutputComponent("bias","default","the instantaneous value of the bias potential");
129  keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential");
130  keys.addOutputComponent("_cntr","default","one or multiple instances of this quantity will be refereceable elsewhere in the input file. "
131  "these quantities will named with the arguments of the bias followed by "
132  "the character string _cntr. These quantities give the instantaneous position "
133  "of the center of the harmonic potential.");
134  keys.addOutputComponent("_work","default","one or multiple instances of this quantity will be refereceable elsewhere in the input file. "
135  "These quantities will named with the arguments of the bias followed by "
136  "the character string _work. These quantities tell the user how much work has "
137  "been done by the potential in dragging the system along the various colvar axis.");
138 }
139 
140 MovingRestraint::MovingRestraint(const ActionOptions&ao):
141 PLUMED_BIAS_INIT(ao),
142 verse(getNumberOfArguments())
143 {
144  parseVector("VERSE",verse);
145  vector<long int> ss(1); ss[0]=-1;
146  std::vector<double> kk( getNumberOfArguments() ), aa( getNumberOfArguments() );
147  for(int i=0;;i++){
148  // Read in step
149  if( !parseNumberedVector("STEP",i,ss) ) break;
150  for(unsigned j=0;j<step.size();j++){
151  if(ss[0]<step[j]) error("in moving restraint step number must always increase");
152  }
153  step.push_back(ss[0]);
154 
155  // Try to read kappa
156  if( !parseNumberedVector("KAPPA",i,kk) ) kk=kappa[i-1];
157  kappa.push_back(kk);
158 
159  // Now read AT
160  if( !parseNumberedVector("AT",i,aa) ) aa=at[i-1];
161  at.push_back(aa);
162  }
163  checkRead();
164 
165  for(unsigned i=0;i<step.size();i++){
166  log.printf(" step%u %ld\n",i,step[i]);
167  log.printf(" at");
168  for(unsigned j=0;j<at[i].size();j++) log.printf(" %f",at[i][j]);
169  log.printf("\n");
170  log.printf(" with force constant");
171  for(unsigned j=0;j<kappa[i].size();j++) log.printf(" %f",kappa[i][j]);
172  log.printf("\n");
173  };
174 
175  addComponent("bias"); componentIsNotPeriodic("bias");
176  addComponent("force2"); componentIsNotPeriodic("force2");
177 
178  // add the centers of the restraint as additional components that can be retrieved (useful for debug)
179 
180  std::string comp;
181  for(int i=0;i< getNumberOfArguments() ;i++){
182  comp=getPntrToArgument(i)->getName()+"_cntr"; // each spring has its own center
184  comp=getPntrToArgument(i)->getName()+"_work"; // each spring has its own work
186  work.push_back(0.); // initialize the work value
187  }
188 
189  log<<" Bibliography ";
190  log<<cite("Grubmuller, Heymann, and Tavan, Science 271, 997 (1996)")<<"\n";
191 
192 }
193 
194 
196  double ene=0.0;
197  double totf2=0.0;
198  unsigned narg=getNumberOfArguments();
199  long int now=getStep();
200  std::vector<double> kk(narg),aa(narg),f(narg);
201  if(now<=step[0]){
202  kk=kappa[0];
203  aa=at[0];
204  oldaa=at[0];
205  oldf.resize(narg);
206  } else if(now>=step[step.size()-1]){
207  kk=kappa[step.size()-1];
208  aa=at[step.size()-1];
209  } else {
210  unsigned i=0;
211  for(i=1;i<step.size();i++) if(now<step[i]) break;
212  double c2=(now-step[i-1])/double(step[i]-step[i-1]);
213  double c1=1.0-c2;
214  for(unsigned j=0;j<narg;j++) kk[j]=(c1*kappa[i-1][j]+c2*kappa[i][j]);
215  for(unsigned j=0;j<narg;j++) aa[j]=(c1*at[i-1][j]+c2*at[i][j]);
216  }
217  for(unsigned i=0;i<narg;++i){
218  const double cv=difference(i,aa[i],getArgument(i)); // this gives: getArgument(i) - aa[i]
219  getPntrToComponent(getPntrToArgument(i)->getName()+"_cntr")->set(aa[i]);
220  const double k=kk[i];
221  f[i]=-k*cv;
222  if(verse[i]=="U" && cv<0) continue;
223  if(verse[i]=="L" && cv>0) continue;
224  plumed_assert(verse[i]=="U" || verse[i]=="L" || verse[i]=="B");
225  if(oldaa.size()==aa.size() && oldf.size()==f.size()) work[i]+=0.5*(oldf[i]+f[i])*(aa[i]-oldaa[i]);
226  getPntrToComponent(getPntrToArgument(i)->getName()+"_work")->set(work[i]);
227  ene+=0.5*k*cv*cv;
228  setOutputForce(i,f[i]);
229  totf2+=f[i]*f[i];
230  };
231  oldf=f;
232  oldaa=aa;
233  getPntrToComponent("bias")->set(ene);
234  getPntrToComponent("force2")->set(totf2);
235 }
236 
237 }
238 }
239 
240 
const std::string & getName() const
Get the name of the quantity.
Definition: Value.h:196
Log & log
Reference to the log stream.
Definition: Action.h:93
void componentIsNotPeriodic(const std::string &name)
Set your value component to have no periodicity.
std::vector< std::vector< double > > kappa
double difference(int, double, double) const
Takes the difference taking into account pbc for arg i.
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.
Value * getPntrToArgument(const unsigned n)
Return a pointer to specific argument.
void addComponent(const std::string &name)
Add a value with a name like label.name.
std::vector< long int > step
std::vector< string > verse
std::vector< double > work
void set(double)
Set the value of the function.
Definition: Value.h:174
std::vector< std::vector< double > > at
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
Provides the keyword MOVINGRESTRAINT
int printf(const char *fmt,...)
Formatted output with explicit format - a la printf.
Definition: OFile.cpp:82
const std::string & getName() const
Returns the name.
Definition: Action.h:268
std::vector< double > oldf
void parseVector(const std::string &key, std::vector< T > &t)
Parse one keyword as std::vector.
Definition: Action.h:311
void calculate()
Calculate an Action.
void setOutputForce(int i, double g)
Definition: Bias.h:56
std::vector< double > oldaa
double getArgument(const unsigned n) const
Returns the value of an argument.
long int getStep() const
Return the present timestep.
Definition: Action.cpp:169
bool parseNumberedVector(const std::string &key, const int no, std::vector< T > &t)
Parse a vector with a number.
Definition: Action.h:352
This is the abstract base class to use for implementing new simulation biases, within it there is inf...
Definition: Bias.h:40
#define PLUMED_BIAS_INIT(ao)
Definition: Bias.h:29
Value * getPntrToComponent(int i)
Return a pointer to the component by index.
unsigned getNumberOfArguments() const
Returns the number of arguments.
std::string cite(const std::string &s)
Cite a paper see PlumedMain::cite.
Definition: Action.cpp:221