Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2016-2018 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 "core/ActionRegister.h" 23 : #include "core/PlumedMain.h" 24 : #include "core/ActionSet.h" 25 : #include "core/ActionShortcut.h" 26 : #include "core/ActionWithValue.h" 27 : 28 : //+PLUMEDOC MCOLVAR DISPLACEMENT 29 : /* 30 : Calculate the displacement vector between the pair of input vectors 31 : 32 : \par Examples 33 : 34 : 35 : */ 36 : //+ENDPLUMEDOC 37 : 38 : namespace PLMD { 39 : namespace refdist { 40 : 41 : class Displacement : public ActionShortcut { 42 : public: 43 : static std::string fixArgumentDot( const std::string& argin ); 44 : static void registerKeywords( Keywords& keys ); 45 : Value* getValueWithLabel( const std::string& name ) const ; 46 : explicit Displacement(const ActionOptions&ao); 47 : }; 48 : 49 : PLUMED_REGISTER_ACTION(Displacement,"DISPLACEMENT") 50 : 51 104 : void Displacement::registerKeywords( Keywords& keys ) { 52 104 : ActionShortcut::registerKeywords(keys); 53 208 : keys.add("compulsory","ARG1","The point that we are calculating the distance from"); 54 208 : keys.add("compulsory","ARG2","The point that we are calculating the distance to"); 55 104 : keys.setValueDescription("the differences between the input arguments"); 56 104 : keys.needsAction("DIFFERENCE"); 57 104 : keys.needsAction("TRANSPOSE"); 58 104 : keys.needsAction("VSTACK"); 59 104 : } 60 : 61 354 : std::string Displacement::fixArgumentDot( const std::string& argin ) { 62 354 : std::string argout = argin; 63 354 : std::size_t dot=argin.find("."); 64 354 : if( dot!=std::string::npos ) { 65 16 : argout = argin.substr(0,dot) + "_" + argin.substr(dot+1); 66 : } 67 354 : return argout; 68 : } 69 : 70 52 : Displacement::Displacement( const ActionOptions& ao): 71 : Action(ao), 72 52 : ActionShortcut(ao) { 73 : // Read in argument names 74 : std::vector<std::string> arg1f, arg2f; 75 52 : parseVector("ARG1",arg1f); 76 104 : parseVector("ARG2",arg2f); 77 : // Check if one of the input arguments is a reference cluster 78 52 : if( arg1f.size()!=arg2f.size() ) { 79 0 : error("number of arguments specified to ARG1 should be same as number for ARG2"); 80 : } 81 : 82 52 : Value* val1=getValueWithLabel( arg1f[0] ); 83 52 : if( arg1f.size()==1 && val1->getRank()!=0 ) { 84 7 : Value* val2=getValueWithLabel( arg2f[0] ); 85 7 : if( val1->getNumberOfValues()==val2->getNumberOfValues() ) { 86 10 : readInputLine( getShortcutLabel() + "_" + fixArgumentDot(arg1f[0]) + "_diff: DIFFERENCE ARG=" + arg1f[0] + "," + arg2f[0] ); 87 10 : readInputLine( getShortcutLabel() + ": TRANSPOSE ARG=" + getShortcutLabel() + "_" + fixArgumentDot(arg1f[0]) + "_diff"); 88 : } else { 89 4 : readInputLine( getShortcutLabel() + ": DIFFERENCE ARG=" + arg1f[0] + "," + arg2f[0] ); 90 : } 91 : } else { 92 217 : for(unsigned i=0; i<arg1f.size(); ++i) { 93 344 : readInputLine( getShortcutLabel() + "_" + fixArgumentDot(arg1f[i]) + "_diff: DIFFERENCE ARG=" + arg1f[i] + "," + arg2f[i] ); 94 : } 95 90 : std::string argdat = "ARG=" + getShortcutLabel() + "_" + fixArgumentDot(arg1f[0]) + "_diff"; 96 172 : for(unsigned i=1; i<arg1f.size(); ++i) { 97 254 : argdat += "," + getShortcutLabel() + "_" + fixArgumentDot(arg1f[i]) + "_diff"; 98 : } 99 90 : readInputLine( getShortcutLabel() + ": VSTACK " + argdat ); 100 : } 101 52 : } 102 : 103 59 : Value* Displacement::getValueWithLabel( const std::string& name ) const { 104 59 : std::size_t dot=name.find("."); 105 59 : std::string sname = name.substr(0,dot); 106 59 : ActionWithValue* vv=plumed.getActionSet().selectWithLabel<ActionWithValue*>( sname ); 107 59 : if( !vv ) { 108 0 : error("cannot find value with name " + name ); 109 : } 110 59 : if( dot==std::string::npos ) { 111 57 : return vv->copyOutput(0); 112 : } 113 2 : if( !vv->exists(name) ) { 114 0 : error("cannot find value with name " + name ); 115 : } 116 2 : return vv->copyOutput( name ); 117 : } 118 : 119 : } 120 : }