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