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 : #include "ActionSet.h" 23 : #include "ActionForInterface.h" 24 : #include "ActionToPutData.h" 25 : #include "ActionWithValue.h" 26 : #include "ActionWithVirtualAtom.h" 27 : #include "GenericMolInfo.h" 28 : #include <algorithm> 29 : 30 : namespace PLMD { 31 : 32 809624 : ActionSet::ActionSet(PlumedMain&p): 33 809624 : plumed(p) { 34 : (void) plumed; // to suppress warning about "unused plumed" 35 809624 : } 36 : 37 809624 : ActionSet::~ActionSet() { 38 : // required in order to deallocate in reverse order: 39 875387 : for(int i=size()-1; i>=0; i--) { 40 65763 : (*this)[i].reset(); 41 : } 42 809624 : } 43 : 44 3 : void ActionSet::clearDelete() { 45 49 : for(int i=size()-1; i>=0; i--) { 46 46 : (*this)[i].reset(); 47 : } 48 3 : clear(); 49 3 : } 50 : 51 9533 : ActionShortcut* ActionSet::getShortcutActionWithLabel( const std::string& s ) const { 52 9533 : updateIndex(); 53 : auto found=index.shortcuts.find(s); 54 9533 : if(found==index.shortcuts.end()) { 55 : return NULL; 56 : } 57 6192 : return found->second; 58 : } 59 : 60 4082 : std::size_t ActionSet::getNumberOfActionsForInterface() const { 61 4082 : updateIndex(); 62 4082 : return index.nforinterface; 63 : } 64 : 65 20231 : GenericMolInfo* ActionSet::selectLatestMolInfo(const Action*action) const { 66 20231 : updateIndex(); 67 : // position of action in the set (actions that are not in the set yet, e.g. the one 68 : // being constructed, come after all the others) 69 : std::size_t pos=size(); 70 : auto found=index.positions.find(action); 71 20231 : if(found!=index.positions.end()) { 72 28 : pos=found->second; 73 : } 74 : GenericMolInfo* latest=nullptr; 75 29652 : for(const auto & m : index.molinfos) { 76 9421 : if(m.first>=pos) { 77 : break; 78 : } 79 9421 : latest=m.second; 80 : } 81 20231 : return latest; 82 : } 83 : 84 28325 : void ActionSet::getAtomValues( std::vector<Value*>& xpos, std::vector<Value*>& ypos, std::vector<Value*>& zpos, std::vector<Value*>& masv, std::vector<Value*>& chargev ) const { 85 28325 : updateIndex(); 86 28325 : xpos.insert(xpos.end(),index.xpos.begin(),index.xpos.end()); 87 28325 : ypos.insert(ypos.end(),index.ypos.begin(),index.ypos.end()); 88 28325 : zpos.insert(zpos.end(),index.zpos.begin(),index.zpos.end()); 89 28325 : if( index.foundpdb ) { 90 : // masses and charges read from a PDB file replace the ones passed by the MD code 91 2 : masv.insert(masv.end(),index.pdbmass.begin(),index.pdbmass.end()); 92 2 : masv.insert(masv.end(),index.vatommass.begin(),index.vatommass.end()); 93 2 : chargev.insert(chargev.end(),index.pdbcharge.begin(),index.pdbcharge.end()); 94 2 : chargev.insert(chargev.end(),index.vatomcharge.begin(),index.vatomcharge.end()); 95 : } else { 96 28323 : masv.insert(masv.end(),index.mass.begin(),index.mass.end()); 97 28323 : chargev.insert(chargev.end(),index.charge.begin(),index.charge.end()); 98 : } 99 28325 : } 100 : 101 431763 : void ActionSet::updateIndex() const { 102 431763 : if( size()<index.nindexed || (index.nindexed>0 && (*this)[index.nindexed-1].get()!=index.last) ) { 103 : // the set has been cleared or modified: start again 104 3 : index=Index(); 105 : } 106 : // look up a label among the actions indexed so far (selectWithLabel would call updateIndex again) 107 4 : auto indexedWithLabel=[this](const std::string& l) -> ActionWithValue* { 108 4 : auto found=index.labels.find(l); 109 4 : if(found!=index.labels.end()) { 110 4 : for(const auto & a : found->second) { 111 4 : if(auto* av=dynamic_cast<ActionWithValue*>(a)) { 112 : return av; 113 : } 114 : } 115 : } 116 : return nullptr; 117 431763 : }; 118 496775 : for(std::size_t i=index.nindexed; i<size(); ++i) { 119 65012 : Action* p=(*this)[i].get(); 120 65012 : index.labels[p->getLabel()].push_back(p); 121 65012 : index.positions[p]=i; 122 65012 : if( auto* sc=dynamic_cast<ActionShortcut*>(p) ) { 123 : // the last shortcut with a given label is returned 124 17888 : index.shortcuts[sc->shortcutlabel]=sc; 125 17888 : if( sc->getName()=="READMASSCHARGE" ) { 126 2 : index.foundpdb=true; 127 2 : ActionWithValue* mv=indexedWithLabel( sc->getShortcutLabel() + "_mass"); 128 2 : plumed_assert( mv ); 129 2 : index.pdbmass.push_back( mv->copyOutput(0) ); 130 2 : ActionWithValue* qv=indexedWithLabel( sc->getShortcutLabel() + "_charges"); 131 2 : plumed_assert( qv ); 132 2 : index.pdbcharge.push_back( qv->copyOutput(0) ); 133 : } 134 : } 135 65012 : if( auto* mi=dynamic_cast<GenericMolInfo*>(p) ) { 136 164 : index.molinfos.emplace_back(i,mi); 137 : } 138 65012 : if( dynamic_cast<ActionForInterface*>(p) ) { 139 17638 : index.nforinterface++; 140 : } 141 65012 : if( auto* vv=dynamic_cast<ActionWithValue*>(p) ) { 142 42807 : if( ActionToPutData* ap=vv->castToActionToPutData() ) { 143 15462 : const std::string role=ap->getRole(); 144 15462 : if( role=="x" ) { 145 2176 : index.xpos.push_back( ap->copyOutput(0) ); 146 : } 147 15462 : if( role=="y" ) { 148 2176 : index.ypos.push_back( ap->copyOutput(0) ); 149 : } 150 15462 : if( role=="z" ) { 151 2176 : index.zpos.push_back( ap->copyOutput(0) ); 152 : } 153 15462 : if( role=="m" ) { 154 2176 : index.mass.push_back( ap->copyOutput(0) ); 155 : } 156 15462 : if( role=="q" ) { 157 2176 : index.charge.push_back( ap->copyOutput(0) ); 158 : } 159 : } 160 42807 : if( vv->castToActionWithVirtualAtom() || vv->getName()=="ARGS2VATOM" ) { 161 10295 : const std::string & l=vv->getLabel(); 162 10295 : index.xpos.push_back( vv->copyOutput( l + ".x") ); 163 10295 : index.ypos.push_back( vv->copyOutput( l + ".y") ); 164 10295 : index.zpos.push_back( vv->copyOutput( l + ".z") ); 165 10295 : index.mass.push_back( vv->copyOutput( l + ".mass") ); 166 10295 : index.charge.push_back( vv->copyOutput( l + ".charge") ); 167 10295 : index.vatommass.push_back( vv->copyOutput( l + ".mass") ); 168 20590 : index.vatomcharge.push_back( vv->copyOutput( l + ".charge") ); 169 : } 170 : } 171 65012 : index.nindexed=i+1; 172 65012 : index.last=p; 173 : } 174 431763 : } 175 : 176 : }