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_FunctionShortcut_h 23 : #define __PLUMED_function_FunctionShortcut_h 24 : 25 : #include "core/ActionShortcut.h" 26 : #include "core/PlumedMain.h" 27 : #include "core/ActionSet.h" 28 : #include "core/ActionRegister.h" 29 : #include "core/ActionWithArguments.h" 30 : #include "core/Value.h" 31 : 32 : namespace PLMD { 33 : namespace function { 34 : 35 : template <class T> 36 : class FunctionShortcut : public ActionShortcut { 37 : private: 38 : /// The function that is being computed 39 : T myfunc; 40 : public: 41 : static void registerKeywords(Keywords&); 42 : explicit FunctionShortcut(const ActionOptions&); 43 : static void createAction( ActionShortcut* action, 44 : const std::vector<Value*>& vals, 45 : const std::string& allargs, 46 : bool useGPU=false); 47 : }; 48 : 49 : template <class T> 50 6800 : void FunctionShortcut<T>::registerKeywords(Keywords& keys ) { 51 6800 : ActionShortcut::registerKeywords( keys ); 52 6800 : keys.reserve("compulsory","PERIODIC", 53 : "if the output of your function is periodic then you should specify " 54 : "the periodicity of the function. " 55 : "If the output is not periodic you must state this using PERIODIC=NO"); 56 6800 : keys.addActionNameSuffix("_SCALAR"); 57 6800 : keys.addActionNameSuffix("_ONEARG"); 58 6800 : keys.addActionNameSuffix("_VECTOR"); 59 6800 : keys.addActionNameSuffix("_VECTORACC"); 60 6800 : keys.addActionNameSuffix("_MATRIX"); 61 6800 : keys.addActionNameSuffix("_MATRIXACC"); 62 13600 : keys.addActionNameSuffix("_GRID"); 63 6800 : keys.addFlag("USEGPU",false,"run this calculation on the GPU"); 64 13600 : keys.addLinkInDocForFlag("USEGPU","plugin_openaccPTM.md"); 65 6800 : T::registerKeywords( keys ); 66 16150 : if( keys.getDisplayName()=="SUM" || keys.getDisplayName()=="CUSTOM" || keys.getDisplayName()=="MATHEVAL" ) { 67 9392 : keys.addInputKeyword("compulsory","ARG","scalar/vector/matrix/grid","the values input to this function"); 68 : } else { 69 4208 : keys.addInputKeyword("compulsory","ARG","scalar/vector/matrix","the values input to this function"); 70 : } 71 13384 : if( keys.outputComponentExists(".#!value") && keys.getDisplayName()!="DIFFERENCE" ) { 72 12434 : keys.addInputKeyword("optional","MASK","vector/matrix", 73 : "the label for a sparse vector/matrix that should be used " 74 : "to determine which elements of the vector/matrix should be computed"); 75 : } 76 6800 : } 77 : 78 : template <class T> 79 4387 : FunctionShortcut<T>::FunctionShortcut(const ActionOptions&ao): 80 : Action(ao), 81 4387 : ActionShortcut(ao) { 82 4387 : std::vector<std::string> args; 83 8774 : parseVector("ARG",args); 84 4387 : if( args.empty() ) { 85 0 : error("no arguments were specified with ARG"); 86 : } 87 4387 : std::string allargs=args[0]; 88 7513 : for(unsigned i=1; i<args.size(); ++i) { 89 6259 : allargs += "," + args[i]; 90 : } 91 4387 : std::vector<Value*> vals; 92 4387 : ActionWithArguments::interpretArgumentList( args, plumed.getActionSet(), this, vals ); 93 4387 : if( vals.size()==0 ) { 94 0 : error("found no input arguments to function"); 95 : } 96 4387 : bool usegpuFLAG=false; 97 4394 : parseFlag("USEGPU",usegpuFLAG); 98 4387 : createAction( this, vals, allargs,usegpuFLAG); 99 4401 : } 100 : 101 : template <class T> 102 4393 : void FunctionShortcut<T>::createAction( ActionShortcut* action, 103 : const std::vector<Value*>& vals, 104 : const std::string& allargs, 105 : const bool useGPU) { 106 4393 : unsigned maxrank=vals[0]->getRank(); 107 : bool isgrid=false; 108 8786 : const std::string doUSEGPU = useGPU?"ACC":""; 109 12011 : for(unsigned i=0; i<vals.size(); ++i) { 110 7618 : if( vals[i]->getRank()>0 && vals[i]->hasDerivatives() ) { 111 : isgrid=true; 112 : } 113 7618 : if( vals[i]->getRank()>maxrank ) { 114 : maxrank=vals[i]->getRank(); 115 : } 116 : } 117 4393 : if( isgrid ) { 118 330 : if( action->plumed.checkAction( action->getName() + "_GRID") ) { 119 660 : action->readInputLine( action->getShortcutLabel() + ": " 120 165 : + action->getName() + "_GRID ARG=" + allargs 121 : + " " + action->convertInputLineToString() ); 122 : } else { 123 0 : plumed_merror("there is no action registered that allows you to do " 124 : + action->getName() + " with functions on a grid"); 125 : } 126 4228 : } else if( maxrank==0 ) { 127 4212 : if( action->plumed.checkAction(action->getName() + "_SCALAR") ) { 128 8424 : action->readInputLine( action->getShortcutLabel() + ": " 129 2106 : + action->getName() + "_SCALAR ARG=" + allargs 130 : + " " + action->convertInputLineToString() ); 131 : } else { 132 0 : plumed_merror("there is no action registered that allows you to do " 133 : + action->getName() + " with scalars"); 134 : } 135 2787 : } else if( vals.size()==1 && action->plumed.checkAction(action->getName() + "_ONEARG") ) { 136 224 : action->readInputLine( action->getShortcutLabel() + ": " 137 56 : + action->getName() + "_ONEARG ARG=" + allargs 138 : + " " + action->convertInputLineToString() ); 139 2066 : } else if( maxrank==1 ) { 140 3258 : if( action->plumed.checkAction( action->getName() + "_VECTOR"+doUSEGPU) ) { 141 8145 : action->readInputLine( action->getShortcutLabel() + ": " 142 1629 : + action->getName() + "_VECTOR"+doUSEGPU+" ARG=" + allargs 143 : + " " + action->convertInputLineToString() ); 144 : } else { 145 0 : plumed_merror("there is no action registered that allows you to do " 146 : + action->getName() + " with vectors"+ (useGPU?" (with USEGPU)":"")); 147 : } 148 437 : } else if( maxrank==2 ) { 149 874 : if( action->plumed.checkAction( action->getName() + "_MATRIX"+doUSEGPU) ) { 150 2192 : action->readInputLine( action->getShortcutLabel() + ": " 151 437 : + action->getName() + "_MATRIX"+doUSEGPU+" ARG=" + allargs 152 : + " " + action->convertInputLineToString() ); 153 : } else { 154 0 : plumed_merror("there is no action registered that allows you to do " 155 : + action->getName() + " with matrices" + (useGPU?" (with USEGPU)":"")); 156 : } 157 : } else { 158 0 : plumed_error(); 159 : } 160 4386 : } 161 : 162 : } 163 : } 164 : #endif