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_COSINE
32 : /*
33 : Fourier cosine basis functions.
34 :
35 : Use as basis functions Fourier cosine series defined on a periodic interval.
36 : You need to provide the periodic interval \f$[a,b]\f$
37 : on which the basis functions are to be used, and the order of the
38 : expansion \f$N\f$ (i.e. the highest Fourier cosine mode used).
39 : The total number of basis functions is \f$N+1\f$ as
40 : the constant \f$f_{0}(x)=1\f$ is also included.
41 : These basis functions should only be used for periodic CVs.
42 : They can be useful if the periodic function being expanded is an
43 : even function, i.e. \f$F(-x)=F(x)\f$.
44 :
45 : The Fourier cosine basis functions are given by
46 : \f{align}{
47 : f_{0}(x) &= 1 \\
48 : f_{1}(x) &= cos(\frac{2\pi }{P} x) \\
49 : f_{2}(x) &= cos(2 \cdot \frac{2\pi}{P} x) \\
50 : f_{3}(x) &= cos(3 \cdot \frac{2\pi}{P} x) \\
51 : & \vdots \\
52 : f_{n}(x) &= cos(n \cdot \frac{2\pi}{P} x) \\
53 : & \vdots \\
54 : f_{N}(x) &= cos(N \cdot \frac{2\pi}{P} x) \\
55 : \f}
56 : where \f$P=(b-a)\f$ is the periodicity of the interval.
57 : They are orthogonal over the interval \f$[a,b]\f$
58 : \f[
59 : \int_{a}^{b} dx \, f_{n}(x)\, f_{m}(x) =
60 : \begin{cases}
61 : 0 & n \neq m \\
62 : (b-a) & n = m = 0 \\
63 : (b-a)/2 & n = m \neq 0
64 : \end{cases}.
65 : \f]
66 :
67 : \par Examples
68 :
69 : Here we employ a Fourier cosine expansion of order 10 over the periodic interval
70 : \f$-\pi\f$ to \f$+\pi\f$.
71 : This results in a total number of 11 basis functions.
72 : The label used to identify the basis function action can then be
73 : referenced later on in the input file.
74 : \plumedfile
75 : BF_COSINE MINIMUM=-pi MAXIMUM=+pi ORDER=10 LABEL=bf1
76 : \endplumedfile
77 :
78 :
79 :
80 : */
81 : //+ENDPLUMEDOC
82 :
83 :
84 4 : class BF_Cosine : public BasisFunctions {
85 : virtual void setupLabels();
86 : virtual void setupUniformIntegrals();
87 : public:
88 : static void registerKeywords(Keywords&);
89 : explicit BF_Cosine(const ActionOptions&);
90 : void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const;
91 : };
92 :
93 :
94 6456 : PLUMED_REGISTER_ACTION(BF_Cosine,"BF_COSINE")
95 :
96 :
97 5 : void BF_Cosine::registerKeywords(Keywords& keys) {
98 5 : BasisFunctions::registerKeywords(keys);
99 5 : }
100 :
101 :
102 4 : BF_Cosine::BF_Cosine(const ActionOptions&ao):
103 4 : PLUMED_VES_BASISFUNCTIONS_INIT(ao)
104 : {
105 4 : setNumberOfBasisFunctions(getOrder()+1);
106 12 : setIntrinsicInterval("-pi","+pi");
107 : setPeriodic();
108 : setIntervalBounded();
109 8 : setType("trigonometric_cos");
110 8 : setDescription("Cosine");
111 4 : setupBF();
112 4 : checkRead();
113 4 : }
114 :
115 :
116 9829 : void BF_Cosine::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
117 : // plumed_assert(values.size()==numberOfBasisFunctions());
118 : // plumed_assert(derivs.size()==numberOfBasisFunctions());
119 9829 : inside_range=true;
120 9829 : argT=translateArgument(arg, inside_range);
121 9829 : values[0]=1.0;
122 9829 : derivs[0]=0.0;
123 206409 : for(unsigned int i=1; i < getOrder()+1; i++) {
124 98290 : double io = i;
125 98290 : double cos_tmp = cos(io*argT);
126 98290 : double sin_tmp = sin(io*argT);
127 196580 : values[i] = cos_tmp;
128 196580 : derivs[i] = -io*sin_tmp*intervalDerivf();
129 : }
130 9829 : if(!inside_range) {
131 2800 : for(unsigned int i=0; i<derivs.size(); i++) {derivs[i]=0.0;}
132 : }
133 9829 : }
134 :
135 :
136 4 : void BF_Cosine::setupLabels() {
137 8 : setLabel(0,"1");
138 84 : for(unsigned int i=1; i < getOrder()+1; i++) {
139 40 : std::string is; Tools::convert(i,is);
140 120 : setLabel(i,"cos("+is+"*s)");
141 : }
142 4 : }
143 :
144 :
145 3 : void BF_Cosine::setupUniformIntegrals() {
146 : setAllUniformIntegralsToZero();
147 : setUniformIntegral(0,1.0);
148 3 : }
149 :
150 :
151 : }
152 4839 : }
|