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