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 7726 : void FunctionShortcut<T>::registerKeywords(Keywords& keys ) { 48 7726 : ActionShortcut::registerKeywords( keys ); 49 7726 : 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"); 50 7726 : keys.addActionNameSuffix("_SCALAR"); 51 7726 : keys.addActionNameSuffix("_VECTOR"); 52 7726 : keys.addActionNameSuffix("_MATRIX"); 53 10699 : keys.addActionNameSuffix("_GRID"); 54 4753 : T tfunc; 55 7726 : tfunc.registerKeywords( keys ); 56 33610 : if( keys.getDisplayName()=="SUM" || keys.getDisplayName()=="CUSTOM" || keys.getDisplayName()=="MATHEVAL" ) { 57 11792 : keys.addInputKeyword("compulsory","ARG","scalar/vector/matrix/grid","the values input to this function"); 58 : } else { 59 3660 : keys.addInputKeyword("compulsory","ARG","scalar/vector/matrix","the values input to this function"); 60 : } 61 7726 : } 62 : 63 : template <class T> 64 4638 : FunctionShortcut<T>::FunctionShortcut(const ActionOptions&ao): 65 : Action(ao), 66 4638 : ActionShortcut(ao) { 67 : std::vector<std::string> args; 68 9276 : parseVector("ARG",args); 69 4638 : std::string allargs=args[0]; 70 7661 : for(unsigned i=1; i<args.size(); ++i) { 71 6051 : allargs += "," + args[i]; 72 : } 73 : std::vector<Value*> vals; 74 4638 : ActionWithArguments::interpretArgumentList( args, plumed.getActionSet(), this, vals ); 75 4638 : if( vals.size()==0 ) { 76 5 : error("found no input arguments to function"); 77 : } 78 4638 : createAction( this, vals, allargs ); 79 4651 : } 80 : 81 : template <class T> 82 4640 : void FunctionShortcut<T>::createAction( ActionShortcut* action, const std::vector<Value*>& vals, const std::string& allargs ) { 83 4640 : unsigned maxrank=vals[0]->getRank(); 84 : bool isgrid=false; 85 12373 : for(unsigned i=0; i<vals.size(); ++i) { 86 7733 : if( vals[i]->getRank()>0 && vals[i]->hasDerivatives() ) { 87 : isgrid=true; 88 : } 89 : if( vals[i]->getRank()>maxrank ) { 90 : maxrank=vals[i]->getRank(); 91 : } 92 : } 93 4640 : if( isgrid ) { 94 866 : if( actionRegister().check( action->getName() + "_GRID") ) { 95 866 : action->readInputLine( action->getShortcutLabel() + ": " + action->getName() + "_GRID ARG=" + allargs + " " + action->convertInputLineToString() ); 96 : } else { 97 0 : plumed_merror("there is no action registered that allows you to do " + action->getName() + " with functions on a grid"); 98 : } 99 4207 : } else if( maxrank==0 ) { 100 2868 : if( actionRegister().check( action->getName() + "_SCALAR") ) { 101 2893 : action->readInputLine( action->getShortcutLabel() + ": " + action->getName() + "_SCALAR ARG=" + allargs + " " + action->convertInputLineToString() ); 102 : } else { 103 0 : plumed_merror("there is no action registered that allows you to do " + action->getName() + " with scalars"); 104 : } 105 2773 : } else if( maxrank==1 ) { 106 4558 : if( actionRegister().check( action->getName() + "_VECTOR") ) { 107 4558 : action->readInputLine( action->getShortcutLabel() + ": " + action->getName() + "_VECTOR ARG=" + allargs + " " + action->convertInputLineToString() ); 108 : } else { 109 0 : plumed_merror("there is no action registered that allows you to do " + action->getName() + " with vectors"); 110 : } 111 494 : } else if( maxrank==2 ) { 112 988 : if( actionRegister().check( action->getName() + "_MATRIX") ) { 113 988 : action->readInputLine( action->getShortcutLabel() + ": " + action->getName() + "_MATRIX ARG=" + allargs + " " + action->convertInputLineToString() ); 114 : } else { 115 0 : plumed_merror("there is no action registered that allows you to do " + action->getName() + " with matrices"); 116 : } 117 : } else { 118 0 : plumed_error(); 119 : } 120 4635 : } 121 : 122 : } 123 : } 124 : #endif