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.add("compulsory","ARG","the argument we are using to build the shortcut"); 52 138 : keys.add("compulsory","COMPONENTS","the components in the input value that you woul like to build a new vector from"); 53 69 : keys.needsAction("FLATTEN"); 54 69 : keys.needsAction("CONSTANT"); 55 69 : keys.needsAction("SELECT_WITH_MASK"); 56 69 : keys.setValueDescription("a vector containing the selected components"); 57 69 : } 58 : 59 57 : SelectComponents::SelectComponents(const ActionOptions& ao): 60 : Action(ao), 61 57 : ActionShortcut(ao) { 62 : std::vector<std::string> argn; 63 114 : parseVector("ARG",argn); 64 : std::vector<Value*> theargs; 65 57 : ActionWithArguments::interpretArgumentList( argn, plumed.getActionSet(), this, theargs ); 66 57 : if( theargs.size()!=1 ) { 67 0 : error("should only be one argument input to this action"); 68 : } 69 : // Create an array that will eventually hold the mask 70 57 : std::vector<double> mask( theargs[0]->getNumberOfValues(), 1 ); 71 : std::vector<std::string> elements; 72 114 : parseVector("COMPONENTS",elements); 73 57 : if( theargs[0]->getRank()==1 ) { 74 189 : for(unsigned i=0; i<elements.size(); ++i) { 75 : unsigned sel; 76 139 : Tools::convert( elements[i], sel ); 77 139 : mask[sel-1]=0; 78 : } 79 7 : } else if( theargs[0]->getRank()==2 ) { 80 27 : for(unsigned i=0; i<elements.size(); ++i) { 81 20 : std::size_t dot = elements[i].find_first_of("."); 82 20 : if( dot==std::string::npos ) { 83 0 : error("found no dot in specification of required matrix element"); 84 : } 85 20 : std::string istr=elements[i].substr(0,dot), jstr=elements[i].substr(dot+1); 86 : unsigned ival, jval; 87 20 : Tools::convert( istr, ival ); 88 20 : Tools::convert( jstr, jval ); 89 20 : mask[(ival-1)*theargs[0]->getShape()[1] + jval - 1] = 0; 90 : } 91 14 : readInputLine( getShortcutLabel() + "_flat: FLATTEN ARG=" + theargs[0]->getName() ); 92 : } else { 93 0 : error("input to this argument should be a vector/matrix"); 94 : } 95 : // Now create the mask action 96 : std::string mask_str; 97 57 : Tools::convert( mask[0], mask_str ); 98 57 : unsigned check_mask=mask[0]; 99 1472 : for(unsigned i=1; i<mask.size(); ++i) { 100 : std::string num; 101 1415 : Tools::convert( mask[i], num ); 102 2830 : mask_str += "," + num; 103 1415 : check_mask +=mask[i]; 104 : } 105 57 : if( mask.size()-check_mask!=elements.size() ) { 106 0 : error("found repeated indexes in COMPONENTS"); 107 : } 108 114 : readInputLine( getShortcutLabel() + "_mask: CONSTANT VALUES=" + mask_str ); 109 : // And finally create the selector 110 57 : if( theargs[0]->getRank()==1 ) { 111 100 : readInputLine( getShortcutLabel() + ": SELECT_WITH_MASK ARG=" + theargs[0]->getName() + " MASK=" + getShortcutLabel() + "_mask"); 112 7 : } else if( theargs[0]->getRank()==2 ) { 113 14 : readInputLine( getShortcutLabel() + ": SELECT_WITH_MASK ARG=" + getShortcutLabel() + "_flat MASK=" + getShortcutLabel() + "_mask"); 114 : } 115 114 : } 116 : 117 : } 118 : }