Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2016-2018 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 12 : class BF_Powers : public BasisFunctions {
81 : double inv_normfactor_;
82 : virtual void setupLabels();
83 : public:
84 : static void registerKeywords( Keywords&);
85 : explicit BF_Powers(const ActionOptions&);
86 : double getValue(const double, const unsigned int, double&, bool&) const;
87 : void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const;
88 : };
89 :
90 :
91 6464 : PLUMED_REGISTER_ACTION(BF_Powers,"BF_POWERS")
92 :
93 :
94 13 : void BF_Powers::registerKeywords(Keywords& keys) {
95 13 : BasisFunctions::registerKeywords(keys);
96 52 : keys.add("optional","NORMALIZATION","The normalization factor that is used to normalize the basis functions. By default it is 1.0.");
97 26 : keys.remove("NUMERICAL_INTEGRALS");
98 13 : }
99 :
100 12 : BF_Powers::BF_Powers(const ActionOptions&ao):
101 12 : PLUMED_VES_BASISFUNCTIONS_INIT(ao)
102 : {
103 12 : setNumberOfBasisFunctions(getOrder()+1);
104 12 : setIntrinsicInterval(intervalMin(),intervalMax());
105 12 : double normfactor_=1.0;
106 24 : parse("NORMALIZATION",normfactor_);
107 12 : if(normfactor_!=1.0) {addKeywordToList("NORMALIZATION",normfactor_);}
108 12 : inv_normfactor_=1.0/normfactor_;
109 : setNonPeriodic();
110 : setIntervalBounded();
111 24 : setType("polynom_powers");
112 24 : setDescription("Polynomial Powers");
113 12 : setupBF();
114 12 : log.printf(" normalization factor: %f\n",normfactor_);
115 12 : checkRead();
116 12 : }
117 :
118 :
119 701701 : void BF_Powers::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
120 701701 : inside_range=true;
121 701701 : argT=checkIfArgumentInsideInterval(arg,inside_range);
122 : //
123 701701 : values[0]=1.0;
124 701701 : derivs[0]=0.0;
125 : //
126 6315309 : for(unsigned int i=1; i < getNumberOfBasisFunctions(); i++) {
127 : // double io = static_cast<double>(i);
128 : // values[i] = pow(argT,io);
129 : // derivs[i] = io*pow(argT,io-1.0);
130 8420412 : values[i] = argT*values[i-1];
131 8420412 : derivs[i]=values[i-1]+argT*derivs[i-1];
132 : }
133 702581 : if(!inside_range) {for(unsigned int i=0; i<derivs.size(); i++) {derivs[i]=0.0;}}
134 701701 : }
135 :
136 :
137 12 : void BF_Powers::setupLabels() {
138 24 : setLabel(0,"1");
139 108 : for(unsigned int i=1; i < getOrder()+1; i++) {
140 48 : std::string is; Tools::convert(i,is);
141 96 : setLabel(i,"s^"+is);
142 : }
143 12 : }
144 :
145 : }
146 4839 : }
|