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_core_ActionSet_h 23 : #define __PLUMED_core_ActionSet_h 24 : 25 : #include "Action.h" 26 : #include "ActionShortcut.h" 27 : #include <memory> 28 : #include <type_traits> 29 : #include <unordered_map> 30 : 31 : namespace PLMD { 32 : 33 : class PlumedMain; 34 : class GenericMolInfo; 35 : class Value; 36 : 37 : /// std::vector containing the sequence of Action to be done. 38 : /// It is a vector of Action*, and as such it has the entire 39 : /// std::vector interface. Moreover, it implements methods to extract 40 : /// Acion* of a given type (select<T>()), NOT of a given type (selectNot<T>()) 41 : /// or to find an Action with a given label (selectWithLabel()) 42 : /// Finally, since it holds pointers, there is a clearDelete() function 43 : /// which deletes the pointers before deleting the vector 44 : class ActionSet: 45 : public std::vector<std::unique_ptr<Action>> { 46 : PlumedMain& plumed; 47 : /// Index of the actions, used to avoid scanning the whole set (with a dynamic_cast 48 : /// per action) every time a new action looks for labels, MOLINFO or atom values. 49 : /// Actions are only appended to the set, so the index is extended lazily with the 50 : /// actions added since the last lookup. It is rebuilt if the set has been cleared. 51 : struct Index { 52 : std::size_t nindexed=0; 53 : const Action* last=nullptr; 54 : std::unordered_map<std::string,std::vector<Action*>> labels; 55 : std::unordered_map<std::string,ActionShortcut*> shortcuts; 56 : std::unordered_map<const Action*,std::size_t> positions; 57 : std::vector<std::pair<std::size_t,GenericMolInfo*>> molinfos; 58 : std::size_t nforinterface=0; 59 : /// atom values, see ActionAtomistic::getAtomValuesFromPlumedObject 60 : bool foundpdb=false; 61 : std::vector<Value*> xpos, ypos, zpos; 62 : std::vector<Value*> pdbmass, pdbcharge; 63 : std::vector<Value*> mass, charge; 64 : std::vector<Value*> vatommass, vatomcharge; 65 : }; 66 : mutable Index index; 67 : void updateIndex() const; 68 : GenericMolInfo* selectLatestMolInfo(const Action*action) const; 69 : public: 70 : explicit ActionSet(PlumedMain&p); 71 : ~ActionSet(); 72 : /// Clear and deletes all the included pointers. 73 : void clearDelete(); 74 : 75 : /// Extract pointers to all Action's of type T 76 : /// To extract all Colvar , use select<Colvar*>(); 77 : template <class T> 78 : std::vector<T> select()const; 79 : /// Extract pointers to all Action's which are not of type T 80 : /// E.g., to extract all noncolvars, use 81 : /// selectNot<Colvar*>(); 82 : template <class T> 83 : std::vector<Action*> selectNot()const; 84 : /// Extract pointer to an action labeled s, only if it is of 85 : /// type T. E.g., to extract an action labeled "pippo", use selectWithLabel<Action*>("pippo") 86 : /// If you want it to be a Colvar, use selectWithLabel<Colvar*>(pippo). If it is 87 : /// not found, it returns NULL 88 : template <class T> 89 : T selectWithLabel(const std::string&s)const; 90 : /// get the labels in the list of actions in form of a string (useful to debug) 91 : /// Only classes that can be dynamic casted to T are reported 92 : template <class T> 93 : std::string getLabelList() const; 94 : /// get the labels in the form of a vector of strings 95 : /// Only classes that can be dynamic casted to T are reported 96 : template <class T> 97 : std::vector<std::string> getLabelVector() const; 98 : /// Extract pointer to last action of type T located before 99 : /// action. If action is not in ActionSet or if there is no action of type T 100 : /// returns NULL. 101 : /// Typically to be used as selectLatest<Type>(this); 102 : template <class T> 103 : T selectLatest(const Action*action)const; 104 : /// Get any shortcuts with this shortcut label 105 : ActionShortcut* getShortcutActionWithLabel( const std::string& s ) const ; 106 : /// Number of actions that are ActionForInterface 107 : std::size_t getNumberOfActionsForInterface() const ; 108 : /// Get the values that hold positions, masses and charges of all the atoms 109 : /// (the MD atoms and the virtual atoms), appending them to the vectors 110 : void getAtomValues( std::vector<Value*>& xpos, std::vector<Value*>& ypos, std::vector<Value*>& zpos, std::vector<Value*>& masv, std::vector<Value*>& chargev ) const ; 111 : }; 112 : 113 : ///// 114 : // INLINE IMPLEMENTATIONS: 115 : 116 : template <class T> 117 27206 : std::vector<T> ActionSet::select()const { 118 27206 : std::vector<T> ret; 119 482773 : for(const auto & p : (*this)) { 120 455567 : T t=dynamic_cast<T>(p.get()); 121 455567 : if(t) { 122 157163 : ret.push_back(t); 123 : } 124 : }; 125 27206 : return ret; 126 0 : } 127 : 128 : template <class T> 129 369592 : T ActionSet::selectWithLabel(const std::string&s)const { 130 369592 : updateIndex(); 131 : auto found=index.labels.find(s); 132 369592 : if(found==index.labels.end()) { 133 : return NULL; 134 : } 135 : // several actions can have the same label (a shortcut and the action it creates): 136 : // the first one of the requested type is returned, as when scanning the set 137 275355 : for(const auto & p : found->second) { 138 250928 : T t=dynamic_cast<T>(p); 139 250928 : if(t) { 140 : return t; 141 : } 142 : } 143 : return NULL; 144 : } 145 : 146 : template <class T> 147 : std::vector<Action*> ActionSet::selectNot()const { 148 : std::vector<Action*> ret; 149 : for(const auto & p : (*this)) { 150 : T t=dynamic_cast<T>(p); 151 : if(!t) { 152 : ret.push_back(p.get()); 153 : } 154 : }; 155 : return ret; 156 : } 157 : 158 : template <class T> 159 1 : std::string ActionSet::getLabelList() const { 160 : std::string outlist; 161 16 : for(const auto & p : (*this)) { 162 15 : if(dynamic_cast<T>(p.get())) { 163 22 : outlist+=p->getLabel()+" "; 164 : } 165 : }; 166 1 : return outlist; 167 : } 168 : 169 : 170 : template <class T> 171 : std::vector<std::string> ActionSet::getLabelVector() const { 172 : std::vector<std::string> outlist; 173 : for(const auto & p : (*this)) { 174 : if(dynamic_cast<T>(p.get())) { 175 : outlist.push_back(p->getLabel()); 176 : } 177 : }; 178 : return outlist; 179 : } 180 : 181 : template <class T> 182 20243 : T ActionSet::selectLatest(const Action*action) const { 183 : if constexpr (std::is_same_v<T,GenericMolInfo*>) { 184 : // indexed, as this is looked up by every ActionAtomistic 185 20231 : return selectLatestMolInfo(action); 186 : } else { 187 : T t=nullptr; 188 114 : for(const auto & p : (*this)) { 189 102 : if(p.get()==action) { 190 : return t; 191 : } 192 102 : T r=dynamic_cast<T>(p.get()); 193 102 : if(r) { 194 : t=r; 195 : } 196 : } 197 : return t; 198 : } 199 : } 200 : 201 : 202 : 203 : } 204 : 205 : #endif 206 :