Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2016-2017 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_HERMITE 32 : /* 33 : Hermite basis functions. 34 : 35 : \par Examples 36 : 37 : */ 38 : //+ENDPLUMEDOC 39 : 40 6 : class BF_Hermite : public BasisFunctions { 41 : double scalingf_; 42 : double center_; 43 : std::vector<double> normf_; 44 : virtual void setupLabels(); 45 : public: 46 : static void registerKeywords(Keywords&); 47 : explicit BF_Hermite(const ActionOptions&); 48 : void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const; 49 : }; 50 : 51 : 52 7836 : PLUMED_REGISTER_ACTION(BF_Hermite,"BF_HERMITE") 53 : 54 : 55 3 : void BF_Hermite::registerKeywords(Keywords& keys) { 56 3 : BasisFunctions::registerKeywords(keys); 57 12 : keys.add("optional","SCALING_FACTOR","scaling factor that is used to define the length scale of the basis functions. Depends also on the order employed. By default it is 1.0"); 58 12 : keys.add("optional","CENTER","the location of the center of the Hermite functions. By default it is 0.0"); 59 6 : keys.remove("NUMERICAL_INTEGRALS"); 60 3 : } 61 : 62 2 : BF_Hermite::BF_Hermite(const ActionOptions&ao): 63 : PLUMED_VES_BASISFUNCTIONS_INIT(ao), 64 : scalingf_(1.0), 65 : center_(0.0), 66 2 : normf_(0) 67 : { 68 2 : setNumberOfBasisFunctions(getOrder()+2); 69 2 : setIntrinsicInterval(intervalMin(),intervalMax()); 70 2 : scalingf_=1.0; 71 4 : parse("SCALING_FACTOR",scalingf_); 72 3 : if(scalingf_!=1.0) {addKeywordToList("SCALING_FACTOR",scalingf_);} 73 2 : center_=0.0; 74 4 : parse("CENTER",center_); 75 3 : if(center_!=0.0) {addKeywordToList("CENTER",center_);} 76 : // 77 : // To normalize with 1.0/sqrt(sqrt(pi)*2^n*n!) 78 2 : normf_.resize(getOrder()+1); 79 2 : normf_[0] = 1.0/(sqrt( sqrt(pi) )); 80 84 : for(unsigned int i=1; i<getOrder()+1; i++) { 81 40 : double io = static_cast<double>(i); 82 120 : normf_[i] = normf_[i-1]*(1.0/sqrt(io*2.0)); 83 : } 84 : // 85 : setNonPeriodic(); 86 : setOrthogonal(); 87 : setIntervalBounded(); 88 4 : setType("Hermite"); 89 4 : setDescription("Hermite functions"); 90 2 : setupBF(); 91 2 : checkRead(); 92 2 : } 93 : 94 : 95 1273555 : void BF_Hermite::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const { 96 : // plumed_assert(values.size()==numberOfBasisFunctions()); 97 : // plumed_assert(derivs.size()==numberOfBasisFunctions()); 98 1273555 : inside_range=true; 99 1273555 : argT=checkIfArgumentInsideInterval(arg,inside_range); 100 1273555 : argT = scalingf_*(argT-center_); 101 : // 102 1273555 : std::vector<double> valuesH(getOrder()+1); 103 1273555 : std::vector<double> derivsH(getOrder()+1); 104 : // 105 : // calculate the Hermite polynomials 106 1273555 : valuesH[0]=1.0; 107 1273555 : derivsH[0]=0.0; 108 1273555 : valuesH[1]=2.0*argT; 109 1273555 : derivsH[1]=2.0; 110 26744655 : for(unsigned int i=1; i < getOrder(); i++) { 111 24197545 : double io = static_cast<double>(i); 112 96790180 : valuesH[i+1] = 2.0*argT*valuesH[i] - 2.0*io*valuesH[i-1]; 113 96790180 : derivsH[i+1] = 2.0*argT*derivsH[i] + 2.0*valuesH[i] - 2.0*io*derivsH[i-1]; 114 : } 115 : // calculate the Hermite functions, the constant has index 0, the index is then shifted 116 : // index 1: exp(-x^2/2)*H0(x) = exp(-x^2/2), index 2: exp(-x^2/2)*H1(x), etc. 117 1273555 : values[0]=1.0; 118 1273555 : derivs[0]=0.0; 119 1273555 : double vexp = exp(-0.5*argT*argT); 120 56036420 : for(unsigned int i=1; i < getNumberOfBasisFunctions(); i++) { 121 106978620 : values[i] = normf_[i-1] * vexp*valuesH[i-1]; 122 80233965 : derivs[i] = normf_[i-1] * scalingf_*vexp*(-argT*valuesH[i-1]+derivsH[i-1]); 123 : } 124 1275265 : if(!inside_range) {for(unsigned int i=0; i<derivs.size(); i++) {derivs[i]=0.0;}} 125 1273555 : } 126 : 127 : 128 2 : void BF_Hermite::setupLabels() { 129 4 : setLabel(0,"1"); 130 88 : for(unsigned int i=1; i < getNumberOfBasisFunctions() ; i++) { 131 42 : std::string is; Tools::convert(i-1,is); 132 126 : setLabel(i,"h"+is+"(s)"); 133 : } 134 2 : } 135 : 136 : 137 : } 138 5874 : }