Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2011-2017 The plumed team 3 : (see the PEOPLE file at the root of the distribution for a list of names) 4 : 5 : See http://www.plumed.org for more information. 6 : 7 : This file is part of plumed, version 2. 8 : 9 : plumed 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 : plumed 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 plumed. If not, see <http://www.gnu.org/licenses/>. 21 : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ 22 : #include "MoreThan.h" 23 : #include "FunctionShortcut.h" 24 : #include "FunctionOfVector.h" 25 : #include "FunctionOfMatrix.h" 26 : #include "core/ActionRegister.h" 27 : 28 : #include <cmath> 29 : 30 : namespace PLMD { 31 : namespace function { 32 : 33 : //+PLUMEDOC FUNCTION MORE_THAN 34 : /* 35 : Use a switching function to determine how many of the input variables are more than a certain cutoff. 36 : 37 : \par Examples 38 : 39 : */ 40 : //+ENDPLUMEDOC 41 : 42 : //+PLUMEDOC FUNCTION MORE_THAN_VECTOR 43 : /* 44 : Use a switching function to determine how many of elements in the input vector are more than a certain cutoff. 45 : 46 : \par Examples 47 : 48 : */ 49 : //+ENDPLUMEDOC 50 : 51 : //+PLUMEDOC COLVAR MORE_THAN_MATRIX 52 : /* 53 : Transform all the elements of a matrix using a switching function that is one when the input value is larger than a threshold 54 : 55 : \par Examples 56 : 57 : */ 58 : //+ENDPLUMEDOC 59 : 60 : typedef FunctionShortcut<MoreThan> MoreThanShortcut; 61 : PLUMED_REGISTER_ACTION(MoreThanShortcut,"MORE_THAN") 62 : typedef FunctionOfVector<MoreThan> VectorMoreThan; 63 : PLUMED_REGISTER_ACTION(VectorMoreThan,"MORE_THAN_VECTOR") 64 : typedef FunctionOfMatrix<MoreThan> MatrixMoreThan; 65 : PLUMED_REGISTER_ACTION(MatrixMoreThan,"MORE_THAN_MATRIX") 66 : 67 252 : void MoreThan::registerKeywords(Keywords& keys) { 68 504 : keys.add("compulsory","NN","6","The n parameter of the switching function "); 69 504 : keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN"); 70 504 : keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function"); 71 504 : keys.add("compulsory","R_0","The r_0 parameter of the switching function"); 72 504 : keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous swiching function defined above. " 73 : "The following provides information on the \\ref switchingfunction that are available. " 74 : "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords."); 75 504 : keys.addFlag("SQUARED",false,"is the input quantity the square of the value that you would like to apply the switching function to"); 76 252 : keys.setValueDescription("a function that is one if the if the input is more than a threshold"); 77 252 : } 78 : 79 68 : void MoreThan::read( ActionWithArguments* action ) { 80 68 : if( action->getNumberOfArguments()!=1 ) { 81 0 : action->error("should only be one argument to more_than actions"); 82 : } 83 68 : if( action->getPntrToArgument(0)->isPeriodic() ) { 84 0 : action->error("cannot use this function on periodic functions"); 85 : } 86 : 87 : 88 : std::string sw,errors; 89 136 : action->parse("SWITCH",sw); 90 68 : if(sw.length()>0) { 91 68 : switchingFunction.set(sw,errors); 92 68 : if( errors.length()!=0 ) { 93 0 : action->error("problem reading SWITCH keyword : " + errors ); 94 : } 95 : } else { 96 0 : int nn=6; 97 0 : int mm=0; 98 0 : double d0=0.0; 99 0 : double r0=0.0; 100 0 : action->parse("R_0",r0); 101 0 : if(r0<=0.0) { 102 0 : action->error("R_0 should be explicitly specified and positive"); 103 : } 104 0 : action->parse("D_0",d0); 105 0 : action->parse("NN",nn); 106 0 : action->parse("MM",mm); 107 0 : switchingFunction.set(nn,mm,r0,d0); 108 : } 109 68 : action->log<<" using switching function with cutoff "<<switchingFunction.description()<<"\n"; 110 68 : action->parseFlag("SQUARED",squared); 111 68 : if( squared ) { 112 6 : action->log<<" input quantity is square of quantity that switching function acts upon\n"; 113 : } 114 68 : } 115 : 116 556662 : void MoreThan::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const { 117 : plumed_dbg_assert( args.size()==1 ); 118 556662 : if( squared ) { 119 469112 : vals[0] = 1.0 - switchingFunction.calculateSqr( args[0], derivatives(0,0) ); 120 : } else { 121 87550 : vals[0] = 1.0 - switchingFunction.calculate( args[0], derivatives(0,0) ); 122 : } 123 556662 : derivatives(0,0) = -args[0]*derivatives(0,0); 124 556662 : } 125 : 126 : } 127 : } 128 : 129 :