Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2012-2023 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 "core/ActionRegister.h" 24 : 25 : namespace PLMD { 26 : namespace bias { 27 : 28 : //+PLUMEDOC BIAS BIASVALUE 29 : /* 30 : Takes the value of one variable and use it as a bias 31 : 32 : This is the simplest possible bias: when you use this method the bias potential is set equal to the scalar-valued argument that was input. 33 : This action is useful for creating custom biasing potential, e.g. if you apply a function (see [function module](module_function.md)) 34 : to some collective variable then use the value of this function directly as a bias. 35 : 36 : This action is also useful for testing that forces are being calculated correctly. If I wanted to test whether the derivatives calculated 37 : by the [DISTANCE](DISTANCE.md) action are computed correctly I would write a PLUMED input like this one: 38 : 39 : ```plumed 40 : d1: DISTANCE ATOMS=1,2 41 : BIASVALUE ARG=d1 42 : ``` 43 : 44 : I would then run a calculation using [driver](driver.md) with the following input: 45 : 46 : ```plumed 47 : plumed driver --ixyz traj.xyz --debug-forces forces.num 48 : ``` 49 : 50 : This outputs a file with two columns that both contain the forces that are acting upon the atoms. The first set of forces output are the 51 : analytic forces that are implemented within PLUMED. The second set of forces are calcluated numerically using finite difference. If you 52 : method is implemented correctly these two sets of forces should be the same. 53 : 54 : ## Examples 55 : 56 : The following input tells plumed to use the value of the distance between atoms 3 and 5 57 : and the value of the distance between atoms 2 and 4 as biases. 58 : It then tells plumed to print the energy of the restraint 59 : 60 : ```plumed 61 : DISTANCE ATOMS=3,5 LABEL=d1 62 : DISTANCE ATOMS=3,6 LABEL=d2 63 : BIASVALUE ARG=d1,d2 LABEL=b 64 : PRINT ARG=d1,d2,b.d1_bias,b.d2_bias 65 : ``` 66 : 67 : Another thing one can do is ask the system to follow a circle in sin/cos in accordance with a time dependence 68 : 69 : ```plumed 70 : t: TIME 71 : # this just print cos and sin of time 72 : cos: MATHEVAL ARG=t VAR=t FUNC=cos(t) PERIODIC=NO 73 : sin: MATHEVAL ARG=t VAR=t FUNC=sin(t) PERIODIC=NO 74 : c1: COM ATOMS=1,2 75 : c2: COM ATOMS=3,4 76 : d: DISTANCE COMPONENTS ATOMS=c1,c2 77 : PRINT ARG=t,cos,sin,d.x,d.y,d.z STRIDE=1 FILE=colvar FMT=%8.4f 78 : # this calculates sine and cosine of a projected component of distance 79 : mycos: MATHEVAL ARG=d.x,d.y VAR=x,y FUNC=x/sqrt(x*x+y*y) PERIODIC=NO 80 : mysin: MATHEVAL ARG=d.x,d.y VAR=x,y FUNC=y/sqrt(x*x+y*y) PERIODIC=NO 81 : # this creates a moving spring so that the system follows a circle-like dynamics 82 : # but it is not a bias, it is a simple value now 83 : vv1: MATHEVAL ARG=mycos,mysin,cos,sin VAR=mc,ms,c,s FUNC=100*((mc-c)^2+(ms-s)^2) PERIODIC=NO 84 : # this takes the value calculated with matheval and uses as a bias 85 : cc: BIASVALUE ARG=vv1 86 : # some printout 87 : PRINT ARG=t,cos,sin,d.x,d.y,d.z,mycos,mysin,cc.vv1_bias STRIDE=1 FILE=colvar FMT=%8.4f 88 : ``` 89 : 90 : */ 91 : //+ENDPLUMEDOC 92 : 93 : class BiasValue : public Bias { 94 : public: 95 : explicit BiasValue(const ActionOptions&); 96 : void calculate() override; 97 : static void registerKeywords(Keywords& keys); 98 : }; 99 : 100 : PLUMED_REGISTER_ACTION(BiasValue,"BIASVALUE") 101 : 102 687 : void BiasValue::registerKeywords(Keywords& keys) { 103 687 : Bias::registerKeywords(keys); 104 1374 : keys.addInputKeyword("compulsory","ARG","scalar/vector","the labels of the scalar arguments whose values will be used as a bias on the system (a vector must have a single element)"); 105 : // Should be _bias below 106 1374 : keys.addOutputComponent("_bias","default","scalar","one or multiple instances of this quantity can be referenced elsewhere in the input file. " 107 : "these quantities will named with the arguments of the bias followed by " 108 : "the character string _bias. These quantities tell the user how much the bias is " 109 : "due to each of the colvars."); 110 1374 : keys.reset_style("NUMERICAL_DERIVATIVES","hidden"); 111 687 : } 112 : 113 669 : BiasValue::BiasValue(const ActionOptions&ao): 114 669 : PLUMED_BIAS_INIT(ao) { 115 668 : checkRead(); 116 : // add one bias for each argument 117 1368 : for(unsigned i=0; i<getNumberOfArguments(); ++i) { 118 700 : std::string ss=getPntrToArgument(i)->getName()+"_bias"; 119 700 : addComponent(ss); 120 700 : componentIsNotPeriodic(ss); 121 : } 122 669 : } 123 : 124 43378 : void BiasValue::calculate() { 125 : double bias=0.0; 126 95028 : for(unsigned i=0; i<getNumberOfArguments(); ++i) { 127 : double val; 128 51650 : val=getArgument(i); 129 51650 : getPntrToComponent(i+1)->set(val); 130 51650 : setOutputForce(i,-1.); 131 51650 : bias+=val; 132 : } 133 43378 : setBias(bias); 134 43378 : } 135 : 136 : } 137 : }