Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2011-2020 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 lugano-2 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 492 : 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 7687 : PLUMED_REGISTER_ACTION(Restraint,"RESTRAINT") 75 : 76 168 : void Restraint::registerKeywords(Keywords& keys) { 77 168 : Bias::registerKeywords(keys); 78 336 : keys.use("ARG"); 79 840 : 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 840 : 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 672 : keys.add("compulsory","AT","the position of the restraint"); 82 672 : keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential"); 83 168 : } 84 : 85 167 : Restraint::Restraint(const ActionOptions&ao): 86 : PLUMED_BIAS_INIT(ao), 87 : at(getNumberOfArguments()), 88 : kappa(getNumberOfArguments(),0.0), 89 659 : slope(getNumberOfArguments(),0.0) 90 : { 91 328 : parseVector("SLOPE",slope); 92 328 : parseVector("KAPPA",kappa); 93 328 : parseVector("AT",at); 94 164 : checkRead(); 95 : 96 164 : log.printf(" at"); 97 919 : for(unsigned i=0; i<at.size(); i++) log.printf(" %f",at[i]); 98 164 : log.printf("\n"); 99 164 : log.printf(" with harmonic force constant"); 100 919 : for(unsigned i=0; i<kappa.size(); i++) log.printf(" %f",kappa[i]); 101 164 : log.printf("\n"); 102 164 : log.printf(" and linear force constant"); 103 919 : for(unsigned i=0; i<slope.size(); i++) log.printf(" %f",slope[i]); 104 164 : log.printf("\n"); 105 : 106 328 : addComponent("force2"); 107 328 : componentIsNotPeriodic("force2"); 108 328 : valueForce2=getPntrToComponent("force2"); 109 164 : } 110 : 111 : 112 4503 : void Restraint::calculate() { 113 : double ene=0.0; 114 : double totf2=0.0; 115 14037 : for(unsigned i=0; i<getNumberOfArguments(); ++i) { 116 4767 : const double cv=difference(i,at[i],getArgument(i)); 117 4767 : const double k=kappa[i]; 118 4767 : const double m=slope[i]; 119 4767 : const double f=-(k*cv+m); 120 4767 : ene+=0.5*k*cv*cv+m*cv; 121 : setOutputForce(i,f); 122 4767 : totf2+=f*f; 123 : } 124 : setBias(ene); 125 4503 : valueForce2->set(totf2); 126 4503 : } 127 : 128 : } 129 : 130 : 131 5517 : }