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, const std::vector<Value*>& vals, const std::string& allargs ); 44 : }; 45 : 46 : template <class T> 47 7785 : void FunctionShortcut<T>::registerKeywords(Keywords& keys ) { 48 7785 : ActionShortcut::registerKeywords( keys ); 49 15570 : keys.add("numbered","ARG","the input to this function"); 50 15570 : keys.reserve("compulsory","PERIODIC","if the output of your function is periodic then you should specify the periodicity of the function. If the output is not periodic you must state this using PERIODIC=NO"); 51 7785 : keys.addActionNameSuffix("_SCALAR"); 52 7785 : keys.addActionNameSuffix("_VECTOR"); 53 7785 : keys.addActionNameSuffix("_MATRIX"); 54 10794 : keys.addActionNameSuffix("_GRID"); 55 4776 : T tfunc; 56 7785 : tfunc.registerKeywords( keys ); 57 7785 : } 58 : 59 : template <class T> 60 4652 : FunctionShortcut<T>::FunctionShortcut(const ActionOptions&ao): 61 : Action(ao), 62 4652 : ActionShortcut(ao) { 63 : std::vector<std::string> args; 64 9304 : parseVector("ARG",args); 65 4652 : std::string allargs=args[0]; 66 7678 : for(unsigned i=1; i<args.size(); ++i) { 67 6057 : allargs += "," + args[i]; 68 : } 69 : std::vector<Value*> vals; 70 4652 : ActionWithArguments::interpretArgumentList( args, plumed.getActionSet(), this, vals ); 71 4652 : if( vals.size()==0 ) { 72 5 : error("found no input arguments to function"); 73 : } 74 4652 : createAction( this, vals, allargs ); 75 4665 : } 76 : 77 : template <class T> 78 4654 : void FunctionShortcut<T>::createAction( ActionShortcut* action, const std::vector<Value*>& vals, const std::string& allargs ) { 79 4654 : unsigned maxrank=vals[0]->getRank(); 80 : bool isgrid=false; 81 12404 : for(unsigned i=0; i<vals.size(); ++i) { 82 7750 : if( vals[i]->getRank()>0 && vals[i]->hasDerivatives() ) { 83 : isgrid=true; 84 : } 85 : if( vals[i]->getRank()>maxrank ) { 86 : maxrank=vals[i]->getRank(); 87 : } 88 : } 89 4654 : if( isgrid ) { 90 866 : if( actionRegister().check( action->getName() + "_GRID") ) { 91 866 : action->readInputLine( action->getShortcutLabel() + ": " + action->getName() + "_GRID ARG=" + allargs + " " + action->convertInputLineToString() ); 92 : } else { 93 0 : plumed_merror("there is no action registered that allows you to do " + action->getName() + " with functions on a grid"); 94 : } 95 4221 : } else if( maxrank==0 ) { 96 2888 : if( actionRegister().check( action->getName() + "_SCALAR") ) { 97 2913 : action->readInputLine( action->getShortcutLabel() + ": " + action->getName() + "_SCALAR ARG=" + allargs + " " + action->convertInputLineToString() ); 98 : } else { 99 0 : plumed_merror("there is no action registered that allows you to do " + action->getName() + " with scalars"); 100 : } 101 2777 : } else if( maxrank==1 ) { 102 4562 : if( actionRegister().check( action->getName() + "_VECTOR") ) { 103 4562 : action->readInputLine( action->getShortcutLabel() + ": " + action->getName() + "_VECTOR ARG=" + allargs + " " + action->convertInputLineToString() ); 104 : } else { 105 0 : plumed_merror("there is no action registered that allows you to do " + action->getName() + " with vectors"); 106 : } 107 496 : } else if( maxrank==2 ) { 108 992 : if( actionRegister().check( action->getName() + "_MATRIX") ) { 109 992 : action->readInputLine( action->getShortcutLabel() + ": " + action->getName() + "_MATRIX ARG=" + allargs + " " + action->convertInputLineToString() ); 110 : } else { 111 0 : plumed_merror("there is no action registered that allows you to do " + action->getName() + " with matrices"); 112 : } 113 : } else { 114 0 : plumed_error(); 115 : } 116 4649 : } 117 : 118 : } 119 : } 120 : #endif