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_LAGUERRE 32 : /* 33 : Laguerre basis functions. 34 : 35 : \par Examples 36 : 37 : */ 38 : //+ENDPLUMEDOC 39 : 40 2 : class BF_Laguerre : public BasisFunctions { 41 : double scalingf_; 42 : virtual void setupLabels(); 43 : public: 44 : static void registerKeywords(Keywords&); 45 : explicit BF_Laguerre(const ActionOptions&); 46 : void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const; 47 : }; 48 : 49 : 50 7836 : PLUMED_REGISTER_ACTION(BF_Laguerre,"BF_LAGUERRE") 51 : 52 : 53 3 : void BF_Laguerre::registerKeywords(Keywords& keys) { 54 3 : BasisFunctions::registerKeywords(keys); 55 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"); 56 6 : keys.remove("NUMERICAL_INTEGRALS"); 57 3 : } 58 : 59 2 : BF_Laguerre::BF_Laguerre(const ActionOptions&ao): 60 : PLUMED_VES_BASISFUNCTIONS_INIT(ao), 61 2 : scalingf_(1.0) 62 : { 63 2 : setNumberOfBasisFunctions(getOrder()+2); 64 2 : setIntrinsicInterval(intervalMin(),intervalMax()); 65 2 : scalingf_ = 1.0; 66 4 : parse("SCALING_FACTOR",scalingf_); 67 3 : if(scalingf_!=1.0) {addKeywordToList("SCALING_FACTOR",scalingf_);} 68 : setNonPeriodic(); 69 : setOrthogonal(); 70 : setIntervalBounded(); 71 4 : setType("Laguerre"); 72 4 : setDescription("Laguerre functions"); 73 2 : setupBF(); 74 2 : checkRead(); 75 2 : } 76 : 77 : 78 1273555 : void BF_Laguerre::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const { 79 : // plumed_assert(values.size()==numberOfBasisFunctions()); 80 : // plumed_assert(derivs.size()==numberOfBasisFunctions()); 81 1273555 : inside_range=true; 82 1273555 : argT=checkIfArgumentInsideInterval(arg,inside_range); 83 2547110 : argT = scalingf_*(argT-intervalMin()); 84 : // 85 1273555 : std::vector<double> valuesL(getOrder()+1); 86 1273555 : std::vector<double> derivsL(getOrder()+1); 87 : // 88 : // calculate the Laguerre polynomials 89 1273555 : valuesL[0]=1.0; 90 1273555 : derivsL[0]=0.0; 91 1273555 : valuesL[1]=1.0-argT; 92 1273555 : derivsL[1]=-1.0; 93 26744655 : for(unsigned int i=1; i < getOrder(); i++) { 94 24197545 : double io = static_cast<double>(i); 95 96790180 : valuesL[i+1] = ((2.0*io+1.0-argT)/(io+1.0))*valuesL[i] - (io/(io+1.0))*valuesL[i-1]; 96 96790180 : derivsL[i+1] = ((2.0*io+1.0-argT)/(io+1.0))*derivsL[i] - (1.0/(io+1.0))*valuesL[i] - (io/(io+1.0))*derivsL[i-1]; 97 : } 98 : // calculate the Laguerre functions, the constant has index 0, the index is then shifted 99 : // index 1: exp(-x/2)*L0(x) = exp(-x/2), index 2: exp(-x/2)*L1(x), etc. 100 1273555 : values[0]=1.0; 101 1273555 : derivs[0]=0.0; 102 1273555 : double vexp = exp(-0.5*argT); 103 56036420 : for(unsigned int i=1; i < getNumberOfBasisFunctions(); i++) { 104 80233965 : values[i] = vexp*valuesL[i-1]; 105 80233965 : derivs[i] = scalingf_*vexp*(-0.5*valuesL[i-1]+derivsL[i-1]); 106 : } 107 1276165 : if(!inside_range) {for(unsigned int i=0; i<derivs.size(); i++) {derivs[i]=0.0;}} 108 1273555 : } 109 : 110 : 111 2 : void BF_Laguerre::setupLabels() { 112 4 : setLabel(0,"1"); 113 88 : for(unsigned int i=1; i < getNumberOfBasisFunctions() ; i++) { 114 42 : std::string is; Tools::convert(i-1,is); 115 126 : setLabel(i,"l"+is+"(s)"); 116 : } 117 2 : } 118 : 119 : 120 : } 121 5874 : }