Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2016-2021 The VES code team 3 : (see the PEOPLE-VES file at the root of this folder for a list of names) 4 : 5 : See http://www.ves-code.org for more information. 6 : 7 : This file is part of VES code module. 8 : 9 : The VES code module 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 : The VES code module 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 the VES code module. If not, see <http://www.gnu.org/licenses/>. 21 : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ 22 : 23 : #include "BasisFunctions.h" 24 : 25 : #include "core/ActionRegister.h" 26 : 27 : 28 : namespace PLMD { 29 : namespace ves { 30 : 31 : //+PLUMEDOC VES_BASISF BF_POWERS 32 : /* 33 : Polynomial power basis functions. 34 : 35 : \attention 36 : __These basis functions should not be used in conventional biasing simulations__. 37 : Instead you should use orthogonal basis functions like Legendre or 38 : Chebyshev polynomials. They are only included for usage in \ref ves_md_linearexpansion 39 : and some special cases. 40 : 41 : Basis functions given by polynomial powers defined on a bounded interval. 42 : You need to provide the interval \f$[a,b]\f$ 43 : on which the basis functions are to be used, and the order of the 44 : expansion \f$N\f$ (i.e. the highest power used). 45 : The total number of basis functions is \f$N+1\f$ as the constant \f$f_{0}(x)=1\f$ 46 : is also included. 47 : These basis functions should not be used for periodic CVs. 48 : 49 : The basis functions are given by 50 : \f{align}{ 51 : f_{0}(x) &= 1 \\ 52 : f_{1}(x) &= x \\ 53 : f_{2}(x) &= x^2 \\ 54 : & \vdots \\ 55 : f_{n}(x) &= x^n \\ 56 : & \vdots \\ 57 : f_{N}(x) &= x^N \\ 58 : \f} 59 : 60 : Note that these basis functions are __not__ orthogonal. In fact the integral 61 : over the uniform target distribution blows up as the interval is increased. 62 : Therefore they should not be used in conventional biasing simulations. 63 : However, they can be useful for usage with \ref ves_md_linearexpansion. 64 : 65 : \par Examples 66 : 67 : Here we employ a polynomial power expansion of order 5 68 : over the interval -2.0 to 2.0. 69 : This results in a total number of 6 basis functions. 70 : The label used to identify the basis function action can then be 71 : referenced later on in the input file. 72 : \plumedfile 73 : BF_POWERS MINIMUM=-2.0 MAXIMUM=2.0 ORDER=5 LABEL=bf_pow 74 : \endplumedfile 75 : 76 : 77 : */ 78 : //+ENDPLUMEDOC 79 : 80 : class BF_Powers : public BasisFunctions { 81 : double inv_normfactor_; 82 : void setupLabels() override; 83 : public: 84 : static void registerKeywords( Keywords&); 85 : explicit BF_Powers(const ActionOptions&); 86 : void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const override; 87 : }; 88 : 89 : 90 10435 : PLUMED_REGISTER_ACTION(BF_Powers,"BF_POWERS") 91 : 92 : 93 17 : void BF_Powers::registerKeywords(Keywords& keys) { 94 17 : BasisFunctions::registerKeywords(keys); 95 34 : keys.add("optional","NORMALIZATION","The normalization factor that is used to normalize the basis functions. By default it is 1.0."); 96 17 : keys.remove("NUMERICAL_INTEGRALS"); 97 17 : } 98 : 99 16 : BF_Powers::BF_Powers(const ActionOptions&ao): 100 16 : PLUMED_VES_BASISFUNCTIONS_INIT(ao) 101 : { 102 16 : setNumberOfBasisFunctions(getOrder()+1); 103 16 : setIntrinsicInterval(intervalMin(),intervalMax()); 104 16 : double normfactor_=1.0; 105 16 : parse("NORMALIZATION",normfactor_); 106 16 : if(normfactor_!=1.0) {addKeywordToList("NORMALIZATION",normfactor_);} 107 16 : inv_normfactor_=1.0/normfactor_; 108 : setNonPeriodic(); 109 : setIntervalBounded(); 110 16 : setType("polynom_powers"); 111 16 : setDescription("Polynomial Powers"); 112 16 : setupBF(); 113 16 : log.printf(" normalization factor: %f\n",normfactor_); 114 16 : checkRead(); 115 16 : } 116 : 117 : 118 842119 : void BF_Powers::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const { 119 842119 : inside_range=true; 120 842119 : argT=checkIfArgumentInsideInterval(arg,inside_range); 121 : // 122 842119 : values[0]=1.0; 123 842119 : derivs[0]=0.0; 124 : // 125 4210595 : for(unsigned int i=1; i < getNumberOfBasisFunctions(); i++) { 126 : // double io = static_cast<double>(i); 127 : // values[i] = pow(argT,io); 128 : // derivs[i] = io*pow(argT,io-1.0); 129 3368476 : values[i] = argT*values[i-1]; 130 3368476 : derivs[i]=values[i-1]+argT*derivs[i-1]; 131 : } 132 842599 : if(!inside_range) {for(unsigned int i=0; i<derivs.size(); i++) {derivs[i]=0.0;}} 133 842119 : } 134 : 135 : 136 16 : void BF_Powers::setupLabels() { 137 16 : setLabel(0,"1"); 138 80 : for(unsigned int i=1; i < getOrder()+1; i++) { 139 64 : std::string is; Tools::convert(i,is); 140 128 : setLabel(i,"s^"+is); 141 : } 142 16 : } 143 : 144 : } 145 : }