Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2017-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 "DataFetchingObject.h" 23 : #include "PlumedMain.h" 24 : #include "ActionSet.h" 25 : #include "Action.h" 26 : #include "ActionWithValue.h" 27 : #include "Value.h" 28 : #include "tools/Tools.h" 29 : #include "tools/TypesafePtr.h" 30 : 31 : namespace PLMD { 32 : 33 : template <class T> 34 : class DataFetchingObjectTyped : public DataFetchingObject { 35 : private: 36 : /// A map containing the data we are grabbing 37 : std::map<std::string,TypesafePtr> data; 38 : public: 39 : explicit DataFetchingObjectTyped(PlumedMain&plumed); 40 1613254 : ~DataFetchingObjectTyped() {} 41 : void setData( const std::string& key, const std::string& type, const TypesafePtr & outval ) override; 42 : void finishDataGrab() override; 43 : }; 44 : 45 806627 : std::unique_ptr<DataFetchingObject> DataFetchingObject::create(unsigned n, PlumedMain& p) { 46 806627 : if(n==sizeof(double)) { 47 806626 : return Tools::make_unique<DataFetchingObjectTyped<double>>(p); 48 1 : } else if(n==sizeof(float)) { 49 1 : return Tools::make_unique<DataFetchingObjectTyped<float>>(p); 50 : } 51 : std::string pp; 52 0 : Tools::convert(n,pp); 53 0 : plumed_merror("cannot create an MD interface with sizeof(real)=="+ pp); 54 : } 55 : 56 806627 : DataFetchingObject::DataFetchingObject(PlumedMain&p): 57 806627 : plumed(p) { 58 806627 : } 59 : 60 258765 : bool DataFetchingObject::activate() const { 61 259405 : for(unsigned j=0; j<myactions.size(); ++j) { 62 640 : myactions[j]->activate(); 63 : } 64 258765 : if( myactions.size()>0 ) { 65 20 : return true; 66 : } 67 : return false; 68 : } 69 : 70 128 : ActionWithValue* DataFetchingObject::findAction( const ActionSet& a, const std::string& key ) { 71 128 : std::string aname = key; 72 128 : std::size_t dot = key.find("."); 73 128 : if( dot!=std::string::npos ) { 74 0 : aname = key.substr(0,dot); 75 : } 76 256 : return a.selectWithLabel<ActionWithValue*>( aname ); 77 : } 78 : 79 64 : void DataFetchingObject::get_rank( const ActionSet& a, const std::string& key, const std::string& type, const TypesafePtr & dims ) { 80 64 : plumed_assert( Tools::getWords(key,"\t\n ,").size()==1 ); 81 64 : plumed_massert( key.find("*")==std::string::npos, "cannot use wildcards in python interface"); 82 : 83 : // Find the appropriate action and store value containing quantity of interest 84 64 : ActionWithValue* myv = findAction( a, key ); 85 64 : Value* val = myv->copyOutput( key ); 86 : 87 : // Now work out what we are returning for this action 88 64 : if( type=="" ) { 89 : // Return a single value in this case 90 64 : dims.set(long(1)); 91 0 : } else if( type=="derivatives" ) { 92 0 : plumed_merror("not yet implemented"); 93 0 : } else if( type=="forces" ) { 94 0 : plumed_merror("not yet implemented"); 95 : } else { 96 0 : plumed_merror("invalid type specifier"); 97 : } 98 64 : } 99 : 100 0 : void DataFetchingObject::get_shape( const ActionSet& a, const std::string& key, const std::string& type, const TypesafePtr & dims ) { 101 0 : plumed_assert( Tools::getWords(key,"\t\n ,").size()==1 ); 102 0 : plumed_massert( key.find("*")==std::string::npos, "cannot use wildcards in python interface"); 103 : 104 : // Find the appropriate action and store value containing quantity of interest 105 0 : ActionWithValue* myv = findAction( a, key ); 106 0 : Value* val = myv->copyOutput( key ); 107 : 108 : // Now work out what we are returning for this action 109 0 : if( type=="" ) { 110 : // Return a single value in this case 111 0 : dims.set(long(1)); 112 0 : } else if( type=="derivatives" ) { 113 0 : plumed_merror("not yet implemented"); 114 0 : } else if( type=="forces" ) { 115 0 : plumed_merror("not yet implemented"); 116 : } else { 117 0 : plumed_merror("invalid type specifier"); 118 : } 119 0 : } 120 : 121 : template <class T> 122 806627 : DataFetchingObjectTyped<T>::DataFetchingObjectTyped(PlumedMain&p): 123 806627 : DataFetchingObject(p) { 124 806627 : } 125 : 126 : template <class T> 127 64 : void DataFetchingObjectTyped<T>::setData( const std::string& key, const std::string& type, const TypesafePtr & outval ) { 128 64 : plumed_assert( Tools::getWords(key,"\t\n ,").size()==1 ); 129 64 : plumed_massert( key.find("*")==std::string::npos, "cannot use wildcards in python interface"); 130 128 : plumed_massert( !data.count(key + " " + type), "already collecting this data elsewhere"); 131 : // Add the space to store the data to the data map 132 64 : T* f=outval.get<T*>(); 133 128 : data.insert(std::pair<std::string,TypesafePtr>(key + " " + type,f)); 134 : 135 : // Find the appropriate action and store value containing quantity of interest 136 64 : ActionWithValue* myv = DataFetchingObject::findAction( plumed.getActionSet(), key ); 137 : // Store the action if not already stored 138 : bool found=false; 139 1056 : for(const auto & p : myactions) { 140 992 : if( p->getLabel()==myv->getLabel() ) { 141 : found=true; 142 : break; 143 : } 144 : } 145 64 : if( !found ) { 146 64 : myactions.push_back( myv ); 147 : } 148 : // Store the value 149 64 : myvalues.push_back( myv->copyOutput( key ) ); 150 64 : } 151 : 152 : template <class T> 153 256378 : void DataFetchingObjectTyped<T>::finishDataGrab() { 154 : // Run over all values and collect data 155 257018 : for(const auto & p : myvalues ) { 156 1280 : auto val=data.find(p->getName() + " "); 157 1280 : if( data.find(p->getName() + " ")!=data.end() ) { 158 640 : val->second.set(static_cast<T>( p->get() )); 159 : } 160 1280 : if( data.find(p->getName() + " derivatives")!=data.end() ) { 161 0 : plumed_merror("not implemented yet"); 162 : } 163 1280 : if( data.find(p->getName() + " forces")!=data.end() ) { 164 0 : plumed_merror("not implemented yet"); 165 : } 166 : } 167 256378 : } 168 : 169 : } 170 :