Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2011-2023 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_FunctionOfScalar_h 23 : #define __PLUMED_function_FunctionOfScalar_h 24 : 25 : #include "Function.h" 26 : #include "FunctionSetup.h" 27 : 28 : namespace PLMD { 29 : namespace function { 30 : 31 : /** 32 : \ingroup INHERIT 33 : This is the abstract base class to use for implementing new CV function, within it there is 34 : \ref AddingAFunction "information" as to how to go about implementing a new function. 35 : */ 36 : 37 : template <class T> 38 : class FunctionOfScalar : public Function { 39 : private: 40 : /// Set equal to one if we are doing evaluateGridFunction 41 : unsigned argstart; 42 : /// The function that is being computed 43 : T myfunc; 44 : public: 45 : explicit FunctionOfScalar(const ActionOptions&); 46 1914 : virtual ~FunctionOfScalar() {} 47 : /// Get the label to write in the graph 48 : std::string writeInGraph() const override ; 49 : std::string getOutputComponentDescription( const std::string& cname, const Keywords& keys ) const override ; 50 : void calculate() override; 51 : static void registerKeywords(Keywords&); 52 : }; 53 : 54 : template <class T> 55 1948 : void FunctionOfScalar<T>::registerKeywords(Keywords& keys) { 56 1948 : Function::registerKeywords(keys); 57 1948 : std::string name = keys.getDisplayName(); 58 1948 : std::size_t und=name.find("_SCALAR"); 59 3896 : keys.setDisplayName( name.substr(0,und) ); 60 1948 : keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log"); 61 1948 : T::registerKeywords( keys ); 62 3896 : if( keys.getDisplayName()=="SUM" ) { 63 0 : keys.setValueDescription("scalar","the sum of all the input arguments"); 64 3896 : } else if( keys.getDisplayName()=="MEAN" ) { 65 0 : keys.setValueDescription("scalar","the mean of all the input arguments"); 66 3896 : } else if( keys.getDisplayName()=="EVALUATE_FUNCTION_FROM_GRID" ) { 67 8 : keys.addInputKeyword("compulsory","ARG","scalar/grid",""); 68 : } 69 1948 : } 70 : 71 : template <class T> 72 962 : FunctionOfScalar<T>::FunctionOfScalar(const ActionOptions&ao): 73 : Action(ao), 74 : Function(ao), 75 962 : argstart(0) { 76 : // Check if first argument is grid 77 962 : if( getPntrToArgument(0)->getRank()>0 && getPntrToArgument(0)->hasDerivatives() ) { 78 1 : argstart=1; 79 : } 80 : // Create the values to hold the output 81 : std::vector<std::size_t> shape; 82 962 : FunctionData<T>::setup( myfunc, keywords.getOutputComponents(), shape, true, this ); 83 967 : } 84 : 85 : template <class T> 86 0 : std::string FunctionOfScalar<T>::writeInGraph() const { 87 0 : std::size_t und = getName().find_last_of("_"); 88 0 : return getName().substr(0,und); 89 : } 90 : 91 : template <class T> 92 3 : std::string FunctionOfScalar<T>::getOutputComponentDescription( const std::string& cname, const Keywords& keys ) const { 93 3 : if( getName().find("SORT")==std::string::npos ) { 94 0 : return ActionWithValue::getOutputComponentDescription( cname, keys ); 95 : } 96 6 : return "the " + cname + "th largest of the input scalars"; 97 : } 98 : 99 : template <class T> 100 93483 : void FunctionOfScalar<T>::calculate() { 101 93483 : std::vector<double> args( getNumberOfArguments() - argstart ); 102 213393 : for(unsigned i=argstart; i<getNumberOfArguments(); ++i) { 103 119910 : args[i-argstart]=getPntrToArgument(i)->get(); 104 : } 105 93483 : std::vector<double> vals( getNumberOfComponents() ), deriv( getNumberOfComponents()*args.size() ); 106 : auto funcout = FunctionOutput::create( getNumberOfComponents(), 107 : vals.data(), 108 : args.size(), 109 : deriv.data() ); 110 93483 : T::calc( myfunc, 111 93483 : doNotCalculateDerivatives(), 112 0 : View<const double>(args.data(),args.size()), 113 : funcout ); 114 187003 : for(unsigned i=0; i<vals.size(); ++i) { 115 93520 : copyOutput(i)->set(vals[i]); 116 : } 117 93483 : if( doNotCalculateDerivatives() ) { 118 : return; 119 : } 120 : unsigned dstart = 0; 121 83238 : for(unsigned i=0; i<argstart; ++i) { 122 1675 : dstart += getPntrToArgument(i)->getNumberOfStoredValues(); 123 : } 124 : 125 163156 : for(unsigned i=0; i<vals.size(); ++i) { 126 81593 : Value* val = getPntrToComponent(i); 127 181447 : for(unsigned j=0; j<args.size(); ++j) { 128 99854 : setDerivative( val, dstart+j, funcout.derivs[i][j] ); 129 : } 130 : } 131 : } 132 : 133 : } 134 : } 135 : #endif