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 : #ifndef __PLUMED_function_Between_h 23 : #define __PLUMED_function_Between_h 24 : #include "FunctionSetup.h" 25 : #include "FunctionShortcut.h" 26 : #include "FunctionOfScalar.h" 27 : #include "FunctionOfVector.h" 28 : #include "FunctionOfMatrix.h" 29 : #include "tools/HistogramBead.h" 30 : 31 : #include <cmath> 32 : 33 : namespace PLMD { 34 : namespace function { 35 : 36 : struct Between { 37 : HistogramBead hist{HistogramBead::KernelType::gaussian,0.0,1.0,0.5}; 38 : static void registerKeywords( Keywords& keys ); 39 : static void read( Between& func, ActionWithArguments* action, 40 : FunctionOptions& options ); 41 : static void calc( const Between& func, 42 : bool noderiv, 43 : const View<const double> args, 44 : FunctionOutput& funcout ); 45 : #ifdef __PLUMED_HAS_OPENACC 46 : void toACCDevice() const { 47 : #pragma acc enter data copyin(this[0:1]) 48 : hist.toACCDevice(); 49 : } 50 : void removeFromACCDevice() const { 51 : hist.removeFromACCDevice(); 52 : #pragma acc exit data delete(this[0:1]) 53 : } 54 : #endif // __PLUMED_HAS_OPENACC 55 : }; 56 : 57 242 : void Between::registerKeywords(Keywords& keys) { 58 242 : keys.add("compulsory","LOWER","the lower boundary for this particular bin"); 59 242 : keys.add("compulsory","UPPER","the upper boundary for this particular bin"); 60 242 : keys.add("compulsory","SMEAR","0.5","the amount to smear the Gaussian for each value in the distribution"); 61 242 : keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous function defined above. " 62 : "The following provides information on the kernel functions that are available. " 63 : "When this keyword is present you no longer need the LOWER, UPPER, SMEAR and KERNEL keywords."); 64 484 : keys.setValueDescription("scalar/vector/matrix","a function that is one if the input falls within a particular range and zero otherwise"); 65 242 : } 66 : 67 58 : void Between::read( Between& func, ActionWithArguments* action, FunctionOptions& options ) { 68 58 : options.derivativeZeroIfValueIsZero = true; 69 58 : if( action->getNumberOfArguments()!=1 ) { 70 0 : ActionWithVector* av = dynamic_cast<ActionWithVector*>( action ); 71 0 : if( !av || (av && action->getNumberOfArguments()-av->getNumberOfMasks()!=1) ) { 72 0 : action->error("should only be one argument to this action"); 73 : } 74 : } 75 : 76 : std::string str_min, str_max; 77 58 : bool isPeriodic = action->getPntrToArgument(0)->isPeriodic(); 78 58 : if( isPeriodic ) { 79 1 : action->getPntrToArgument(0)->getDomain( str_min, str_max ); 80 : } 81 : std::string hinput; 82 116 : action->parse("SWITCH",hinput); 83 58 : if(hinput.length()==0) { 84 : std::string low, up, sme; 85 6 : action->parse("LOWER",low); 86 6 : action->parse("UPPER",up); 87 6 : action->parse("SMEAR",sme); 88 18 : hinput = "GAUSSIAN LOWER=" + low + " UPPER=" + up + " SMEAR=" + sme; 89 : } 90 : std::string errors; 91 58 : func.hist.set( hinput, errors ); 92 58 : if( errors.size()!=0 ) { 93 0 : action->error( errors ); 94 : } 95 58 : action->log.printf(" %s \n", func.hist.description().c_str() ); 96 : 97 58 : if( !isPeriodic ) { 98 : func.hist.isNotPeriodic(); 99 : } else { 100 : double min; 101 : double max; 102 1 : Tools::convert( str_min, min ); 103 1 : Tools::convert( str_max, max ); 104 1 : func.hist.isPeriodic( min, max ); 105 : } 106 64 : } 107 : 108 99314 : void Between::calc( const Between& func, 109 : bool noderiv, 110 : const View<const double> args, 111 : FunctionOutput& funcout ) { 112 : // the presence of NDEBUG seems to be ignored by nvcc... 113 : // plumed_dbg_assert( args.size()==1 ); 114 : double deriv; 115 99314 : funcout.values[0] = func.hist.calculate( args[0], deriv ); 116 99314 : if( !noderiv ) { 117 48885 : funcout.derivs[0][0] = deriv; 118 : } 119 99314 : } 120 : 121 : } 122 : } 123 : #endif //__PLUMED_function_Between_h