Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2011-2019 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.org for more information.
6 :
7 : This file is part of plumed, version 2.
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 RESTRAINT
33 : /*
34 : Adds harmonic and/or linear restraints on one or more variables.
35 :
36 : Either or both
37 : of SLOPE and KAPPA must be present to specify the linear and harmonic force constants
38 : respectively. The resulting potential is given by:
39 : \f[
40 : \sum_i \frac{k_i}{2} (x_i-a_i)^2 + m_i*(x_i-a_i)
41 : \f].
42 :
43 : The number of components for any vector of force constants must be equal to the number
44 : of arguments to the action.
45 :
46 : Additional material and examples can be also found in the tutorial \ref belfast-4
47 :
48 : \par Examples
49 :
50 : The following input tells plumed to restrain the distance between atoms 3 and 5
51 : and the distance between atoms 2 and 4, at different equilibrium
52 : values, and to print the energy of the restraint
53 : \plumedfile
54 : DISTANCE ATOMS=3,5 LABEL=d1
55 : DISTANCE ATOMS=2,4 LABEL=d2
56 : RESTRAINT ARG=d1,d2 AT=1.0,1.5 KAPPA=150.0,150.0 LABEL=restraint
57 : PRINT ARG=restraint.bias
58 : \endplumedfile
59 :
60 : */
61 : //+ENDPLUMEDOC
62 :
63 435 : class Restraint : public Bias {
64 : std::vector<double> at;
65 : std::vector<double> kappa;
66 : std::vector<double> slope;
67 : Value* valueForce2;
68 : public:
69 : explicit Restraint(const ActionOptions&);
70 : void calculate();
71 : static void registerKeywords(Keywords& keys);
72 : };
73 :
74 6599 : PLUMED_REGISTER_ACTION(Restraint,"RESTRAINT")
75 :
76 148 : void Restraint::registerKeywords(Keywords& keys) {
77 148 : Bias::registerKeywords(keys);
78 296 : keys.use("ARG");
79 740 : keys.add("compulsory","SLOPE","0.0","specifies that the restraint is linear and what the values of the force constants on each of the variables are");
80 740 : keys.add("compulsory","KAPPA","0.0","specifies that the restraint is harmonic and what the values of the force constants on each of the variables are");
81 592 : keys.add("compulsory","AT","the position of the restraint");
82 592 : keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential");
83 148 : }
84 :
85 147 : Restraint::Restraint(const ActionOptions&ao):
86 : PLUMED_BIAS_INIT(ao),
87 : at(getNumberOfArguments()),
88 : kappa(getNumberOfArguments(),0.0),
89 582 : slope(getNumberOfArguments(),0.0)
90 : {
91 290 : parseVector("SLOPE",slope);
92 290 : parseVector("KAPPA",kappa);
93 290 : parseVector("AT",at);
94 145 : checkRead();
95 :
96 145 : log.printf(" at");
97 824 : for(unsigned i=0; i<at.size(); i++) log.printf(" %f",at[i]);
98 145 : log.printf("\n");
99 145 : log.printf(" with harmonic force constant");
100 824 : for(unsigned i=0; i<kappa.size(); i++) log.printf(" %f",kappa[i]);
101 145 : log.printf("\n");
102 145 : log.printf(" and linear force constant");
103 824 : for(unsigned i=0; i<slope.size(); i++) log.printf(" %f",slope[i]);
104 145 : log.printf("\n");
105 :
106 290 : addComponent("force2");
107 290 : componentIsNotPeriodic("force2");
108 290 : valueForce2=getPntrToComponent("force2");
109 145 : }
110 :
111 :
112 1931 : void Restraint::calculate() {
113 : double ene=0.0;
114 : double totf2=0.0;
115 6321 : for(unsigned i=0; i<getNumberOfArguments(); ++i) {
116 2195 : const double cv=difference(i,at[i],getArgument(i));
117 2195 : const double k=kappa[i];
118 2195 : const double m=slope[i];
119 2195 : const double f=-(k*cv+m);
120 2195 : ene+=0.5*k*cv*cv+m*cv;
121 : setOutputForce(i,f);
122 2195 : totf2+=f*f;
123 : }
124 : setBias(ene);
125 1931 : valueForce2->set(totf2);
126 1931 : }
127 :
128 : }
129 :
130 :
131 4839 : }
|