Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2014-2017 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/ActionShortcut.h" 23 : #include "core/ActionRegister.h" 24 : #include "core/ActionWithArguments.h" 25 : #include "core/PlumedMain.h" 26 : #include "core/ActionSet.h" 27 : 28 : //+PLUMEDOC PRINTANALYSIS SELECT_COMPONENTS 29 : /* 30 : Create a new value to hold a subset of the components that are in a vector or matrix 31 : 32 : \par Examples 33 : 34 : */ 35 : //+ENDPLUMEDOC 36 : 37 : namespace PLMD { 38 : namespace valtools { 39 : 40 : class SelectComponents : public ActionShortcut { 41 : public: 42 : static void registerKeywords( Keywords& keys ); 43 : /// Constructor 44 : explicit SelectComponents(const ActionOptions&); 45 : }; 46 : 47 : PLUMED_REGISTER_ACTION(SelectComponents,"SELECT_COMPONENTS") 48 : 49 69 : void SelectComponents::registerKeywords( Keywords& keys ) { 50 69 : ActionShortcut::registerKeywords( keys ); 51 138 : keys.addInputKeyword("compulsory","ARG","vector/matrix","the value from which we are selecting components"); 52 138 : keys.add("compulsory","COMPONENTS","the components in the input value that you woul like to build a new vector from"); 53 207 : keys.needsAction("FLATTEN"); keys.needsAction("CONSTANT"); keys.needsAction("SELECT_WITH_MASK"); 54 138 : keys.setValueDescription("vector","a vector containing the selected components"); 55 69 : } 56 : 57 57 : SelectComponents::SelectComponents(const ActionOptions& ao): 58 : Action(ao), 59 57 : ActionShortcut(ao) 60 : { 61 114 : std::vector<std::string> argn; parseVector("ARG",argn); std::vector<Value*> theargs; 62 57 : ActionWithArguments::interpretArgumentList( argn, plumed.getActionSet(), this, theargs ); 63 57 : if( theargs.size()!=1 ) error("should only be one argument input to this action"); 64 : // Create an array that will eventually hold the mask 65 57 : std::vector<double> mask( theargs[0]->getNumberOfValues(), 1 ); 66 114 : std::vector<std::string> elements; parseVector("COMPONENTS",elements); 67 57 : if( theargs[0]->getRank()==1 ) { 68 189 : for(unsigned i=0; i<elements.size(); ++i) { unsigned sel; Tools::convert( elements[i], sel ); mask[sel-1]=0; } 69 7 : } else if( theargs[0]->getRank()==2 ) { 70 27 : for(unsigned i=0; i<elements.size(); ++i) { 71 20 : std::size_t dot = elements[i].find_first_of("."); 72 20 : if( dot==std::string::npos ) error("found no dot in specification of required matrix element"); 73 20 : std::string istr=elements[i].substr(0,dot), jstr=elements[i].substr(dot+1); 74 20 : unsigned ival, jval; Tools::convert( istr, ival ); Tools::convert( jstr, jval ); 75 20 : mask[(ival-1)*theargs[0]->getShape()[1] + jval - 1] = 0; 76 : } 77 14 : readInputLine( getShortcutLabel() + "_flat: FLATTEN ARG=" + theargs[0]->getName() ); 78 0 : } else error("input to this argument should be a vector/matrix"); 79 : // Now create the mask action 80 57 : std::string mask_str; Tools::convert( mask[0], mask_str ); unsigned check_mask=mask[0]; 81 1472 : for(unsigned i=1; i<mask.size(); ++i) { std::string num; Tools::convert( mask[i], num ); mask_str += "," + num; check_mask +=mask[i]; } 82 57 : if( mask.size()-check_mask!=elements.size() ) error("found repeated indexes in COMPONENTS"); 83 114 : readInputLine( getShortcutLabel() + "_mask: CONSTANT VALUES=" + mask_str ); 84 : // And finally create the selector 85 107 : if( theargs[0]->getRank()==1 ) readInputLine( getShortcutLabel() + ": SELECT_WITH_MASK ARG=" + theargs[0]->getName() + " MASK=" + getShortcutLabel() + "_mask"); 86 14 : else if( theargs[0]->getRank()==2 ) readInputLine( getShortcutLabel() + ": SELECT_WITH_MASK ARG=" + getShortcutLabel() + "_flat MASK=" + getShortcutLabel() + "_mask"); 87 114 : } 88 : 89 : } 90 : }