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 : 37 : __These basis functions should not be used in conventional biasing simulations__. 38 : Instead you should use orthogonal basis functions like Legendre or 39 : Chebyshev polynomials. They are only included for usage in [ves_md_linearexpansion](ves_md_linearexpansion.md) 40 : and some special cases. 41 : 42 : Basis functions given by polynomial powers defined on a bounded interval. 43 : You need to provide the interval $[a,b]$ 44 : on which the basis functions are to be used, and the order of the 45 : expansion $N$ (i.e. the highest power used). 46 : The total number of basis functions is $N+1$ as the constant $f_{0}(x)=1$ 47 : is also included. 48 : These basis functions should not be used for periodic CVs. 49 : 50 : The basis functions are given by 51 : 52 : $$ 53 : \begin{aligned} 54 : f_{0}(x) &= 1 \\ 55 : f_{1}(x) &= x \\ 56 : f_{2}(x) &= x^2 \\ 57 : & \vdots \\ 58 : f_{n}(x) &= x^n \\ 59 : & \vdots \\ 60 : f_{N}(x) &= x^N \\ 61 : \end{aligned} 62 : $$ 63 : 64 : Note that these basis functions are __not__ orthogonal. In fact the integral 65 : over the uniform target distribution blows up as the interval is increased. 66 : Therefore they should not be used in conventional biasing simulations. 67 : However, they can be useful for usage with [ves_md_linearexpansion](ves_md_linearexpansion.md). 68 : 69 : ## Examples 70 : 71 : Here we employ a polynomial power expansion of order 5 72 : over the interval -2.0 to 2.0. 73 : This results in a total number of 6 basis functions. 74 : The label used to identify the basis function action can then be 75 : referenced later on in the input file. 76 : 77 : ```plumed 78 : BF_POWERS MINIMUM=-2.0 MAXIMUM=2.0 ORDER=5 LABEL=bf_pow 79 : ``` 80 : 81 : 82 : */ 83 : //+ENDPLUMEDOC 84 : 85 : class BF_Powers : public BasisFunctions { 86 : double inv_normfactor_; 87 : void setupLabels() override; 88 : public: 89 : static void registerKeywords( Keywords&); 90 : explicit BF_Powers(const ActionOptions&); 91 : void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const override; 92 : }; 93 : 94 : 95 : PLUMED_REGISTER_ACTION(BF_Powers,"BF_POWERS") 96 : 97 : 98 18 : void BF_Powers::registerKeywords(Keywords& keys) { 99 18 : BasisFunctions::registerKeywords(keys); 100 18 : keys.add("optional","NORMALIZATION","The normalization factor that is used to normalize the basis functions. By default it is 1.0."); 101 18 : keys.remove("NUMERICAL_INTEGRALS"); 102 18 : } 103 : 104 16 : BF_Powers::BF_Powers(const ActionOptions&ao): 105 16 : PLUMED_VES_BASISFUNCTIONS_INIT(ao) { 106 16 : setNumberOfBasisFunctions(getOrder()+1); 107 16 : setIntrinsicInterval(intervalMin(),intervalMax()); 108 16 : double normfactor_=1.0; 109 16 : parse("NORMALIZATION",normfactor_); 110 16 : if(normfactor_!=1.0) { 111 0 : addKeywordToList("NORMALIZATION",normfactor_); 112 : } 113 16 : inv_normfactor_=1.0/normfactor_; 114 : setNonPeriodic(); 115 : setIntervalBounded(); 116 16 : setType("polynom_powers"); 117 16 : setDescription("Polynomial Powers"); 118 16 : setupBF(); 119 16 : log.printf(" normalization factor: %f\n",normfactor_); 120 16 : checkRead(); 121 16 : } 122 : 123 : 124 842119 : void BF_Powers::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const { 125 842119 : inside_range=true; 126 842119 : argT=checkIfArgumentInsideInterval(arg,inside_range); 127 : // 128 842119 : values[0]=1.0; 129 842119 : derivs[0]=0.0; 130 : // 131 4210595 : for(unsigned int i=1; i < getNumberOfBasisFunctions(); i++) { 132 : // double io = static_cast<double>(i); 133 : // values[i] = pow(argT,io); 134 : // derivs[i] = io*pow(argT,io-1.0); 135 3368476 : values[i] = argT*values[i-1]; 136 3368476 : derivs[i]=values[i-1]+argT*derivs[i-1]; 137 : } 138 842119 : if(!inside_range) { 139 480 : for(unsigned int i=0; i<derivs.size(); i++) { 140 400 : derivs[i]=0.0; 141 : } 142 : } 143 842119 : } 144 : 145 : 146 16 : void BF_Powers::setupLabels() { 147 16 : setLabel(0,"1"); 148 80 : for(unsigned int i=1; i < getOrder()+1; i++) { 149 : std::string is; 150 64 : Tools::convert(i,is); 151 128 : setLabel(i,"s^"+is); 152 : } 153 16 : } 154 : 155 : } 156 : }