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_CUBIC_B_SPLINES 32 : /* 33 : Cubic B spline basis functions 34 : 35 : \par Examples 36 : 37 : \par Test 38 : 39 : */ 40 : //+ENDPLUMEDOC 41 : 42 2 : class BF_CubicBspline : public BasisFunctions { 43 : double spacing_; 44 : double inv_spacing_; 45 : double inv_normfactor_; 46 : double spline(const double, double&) const; 47 : public: 48 : static void registerKeywords( Keywords&); 49 : explicit BF_CubicBspline(const ActionOptions&); 50 : void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const; 51 : }; 52 : 53 : 54 7836 : PLUMED_REGISTER_ACTION(BF_CubicBspline,"BF_CUBIC_B_SPLINES") 55 : 56 : // See DOI 10.1007/s10614-007-9092-4 for more information; 57 : 58 : 59 3 : void BF_CubicBspline::registerKeywords(Keywords& keys) { 60 3 : BasisFunctions::registerKeywords(keys); 61 12 : keys.add("optional","NORMALIZATION","the normalization factor that is used to normalize the basis functions by dividing the values. By default it is 2."); 62 6 : keys.remove("NUMERICAL_INTEGRALS"); 63 3 : } 64 : 65 2 : BF_CubicBspline::BF_CubicBspline(const ActionOptions&ao): 66 2 : PLUMED_VES_BASISFUNCTIONS_INIT(ao) 67 : { 68 2 : setNumberOfBasisFunctions((getOrder()+3)+1); 69 2 : setIntrinsicInterval(intervalMin(),intervalMax()); 70 4 : spacing_=(intervalMax()-intervalMin())/static_cast<double>(getOrder()); 71 2 : inv_spacing_ = 1.0/spacing_; 72 2 : double normfactor_=2.0; 73 4 : parse("NORMALIZATION",normfactor_); 74 2 : if(normfactor_!=2.0) {addKeywordToList("NORMALIZATION",normfactor_);} 75 2 : inv_normfactor_=1.0/normfactor_; 76 : setNonPeriodic(); 77 : setNonOrthogonal(); 78 : setIntervalBounded(); 79 4 : setType("splines_2nd-order"); 80 4 : setDescription("Cubic B-splines (2nd order splines)"); 81 4 : setLabelPrefix("S"); 82 2 : setupBF(); 83 2 : log.printf(" normalization factor: %f\n",normfactor_); 84 2 : checkRead(); 85 2 : } 86 : 87 : 88 1209031 : void BF_CubicBspline::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const { 89 : // plumed_assert(values.size()==numberOfBasisFunctions()); 90 : // plumed_assert(derivs.size()==numberOfBasisFunctions()); 91 1209031 : inside_range=true; 92 1209031 : argT=checkIfArgumentInsideInterval(arg,inside_range); 93 : // 94 1209031 : values[0]=1.0; 95 1209031 : derivs[0]=0.0; 96 : // 97 58033488 : for(unsigned int i=1; i < getNumberOfBasisFunctions(); i++) { 98 55615426 : double argx = ((argT-intervalMin())*inv_spacing_) - (static_cast<double>(i)-2.0); 99 55615426 : values[i] = spline(argx, derivs[i]); 100 27807713 : derivs[i]*=inv_spacing_; 101 : } 102 1212951 : if(!inside_range) {for(unsigned int i=0; i<derivs.size(); i++) {derivs[i]=0.0;}} 103 1209031 : } 104 : 105 : 106 27807713 : double BF_CubicBspline::spline(const double arg, double& deriv) const { 107 : double value=0.0; 108 : double x=arg; 109 : // derivative of abs(x); 110 : double dx = 1.0; 111 27807713 : if(x < 0) { 112 13902443 : x=-x; 113 : dx = -1.0; 114 : } 115 : // 116 27807713 : if(x > 2) { 117 : value=0.0; 118 22971416 : deriv=0.0; 119 : } 120 4836297 : else if(x >= 1) { 121 2420913 : value = ((2.0-x)*(2.0-x)*(2.0-x)); 122 2420913 : deriv = dx*(-3.0*(2.0-x)*(2.0-x)); 123 : // value=((2.0-x)*(2.0-x)*(2.0-x))/6.0; 124 : // deriv=-x*x*(2.0-x)*(2.0-x); 125 : } 126 : else { 127 2415384 : value = 4.0-6.0*x*x+3.0*x*x*x; 128 2415384 : deriv = dx*(-12.0*x+9.0*x*x); 129 : // value=x*x*x*0.5-x*x+2.0/3.0; 130 : // deriv=(3.0/2.0)*x*x-2.0*x; 131 : } 132 27807713 : value *= inv_normfactor_; 133 27807713 : deriv *= inv_normfactor_; 134 27807713 : return value; 135 : } 136 : 137 : 138 : } 139 5874 : }