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/ActionWithValue.h" 23 : #include "core/ActionWithArguments.h" 24 : #include "core/ActionRegister.h" 25 : #include "core/PlumedMain.h" 26 : #include "core/ActionSet.h" 27 : #include "ClusteringBase.h" 28 : 29 : //+PLUMEDOC CONCOMP CLUSTER_WEIGHTS 30 : /* 31 : Setup a vector that has one for all the atoms that form part of the cluster of interest and that has zero for all other atoms. 32 : 33 : \par Examples 34 : 35 : 36 : */ 37 : //+ENDPLUMEDOC 38 : 39 : namespace PLMD { 40 : namespace clusters { 41 : 42 : class ClusterWeights : 43 : public ActionWithArguments, 44 : public ActionWithValue { 45 : private: 46 : /// The cluster we are looking for 47 : unsigned clustr; 48 : /// The forces 49 : std::vector<double> forcesToApply; 50 : public: 51 : /// Create manual 52 : static void registerKeywords( Keywords& keys ); 53 : /// Constructor 54 : explicit ClusterWeights(const ActionOptions&); 55 : /// The number of derivatives 56 : unsigned getNumberOfDerivatives() override ; 57 : /// Do the calculation 58 : void calculate() override ; 59 : /// 60 51 : void apply() override {} 61 : }; 62 : 63 : PLUMED_REGISTER_ACTION(ClusterWeights,"CLUSTER_WEIGHTS") 64 : 65 57 : void ClusterWeights::registerKeywords( Keywords& keys ) { 66 57 : Action::registerKeywords( keys ); 67 57 : ActionWithArguments::registerKeywords( keys ); 68 57 : ActionWithValue::registerKeywords( keys ); keys.remove("NUMERICAL_DERIVATIVES"); 69 114 : keys.addInputKeyword("compulsory","CLUSTERS","vector","the label of the action that does the clustering"); 70 114 : keys.add("compulsory","CLUSTER","1","which cluster would you like to look at 1 is the largest cluster, 2 is the second largest, 3 is the the third largest and so on."); 71 114 : keys.addFlag("LOWMEM",false,"this flag does nothing and is present only to ensure back-compatibility"); 72 : // keys.add("hidden","FROM_PROPERTIES","indicates that this is created from CLUSTER_PROPERTIES shortcut"); 73 114 : keys.setValueDescription("vector","vector with elements that are one if the atom of interest is part of the required cluster and zero otherwise"); 74 57 : } 75 : 76 29 : ClusterWeights::ClusterWeights(const ActionOptions&ao): 77 : Action(ao), 78 : ActionWithArguments(ao), 79 29 : ActionWithValue(ao) 80 : { 81 29 : bool lowmem; parseFlag("LOWMEM",lowmem); 82 29 : if( lowmem ) warning("LOWMEM flag is deprecated and is no longer required for this action"); 83 : // Read in the clustering object 84 58 : std::vector<Value*> clusters; parseArgumentList("CLUSTERS",clusters); 85 29 : if( clusters.size()!=1 ) error("should pass only one matrix to clustering base"); 86 29 : ClusteringBase* cc = dynamic_cast<ClusteringBase*>( clusters[0]->getPntrToAction() ); 87 29 : if( !cc ) error("input to CLUSTERS keyword should be a clustering action"); 88 : // Request the arguments 89 29 : requestArguments( clusters ); 90 : // Now create the value 91 29 : std::vector<unsigned> shape(1); shape[0]=clusters[0]->getShape()[0]; 92 29 : addValue( shape ); setNotPeriodic(); getPntrToComponent(0)->buildDataStore(); 93 : // Find out which cluster we want 94 29 : parse("CLUSTER",clustr); 95 29 : if( clustr<1 ) error("cannot look for a cluster larger than the largest cluster"); 96 29 : if( clustr>clusters[0]->getShape()[0] ) error("cluster selected is invalid - too few atoms in system"); 97 29 : log.printf(" atoms in %dth largest cluster calculated by %s are equal to one \n",clustr, cc->getLabel().c_str() ); 98 29 : } 99 : 100 24 : unsigned ClusterWeights::getNumberOfDerivatives() { 101 24 : return 0; 102 : } 103 : 104 51 : void ClusterWeights::calculate() { 105 51 : plumed_assert( getPntrToArgument(0)->valueHasBeenSet() ); 106 36627 : for(unsigned i=0; i<getPntrToArgument(0)->getShape()[0]; ++i) { 107 36576 : if( fabs(getPntrToArgument(0)->get(i)-clustr)<epsilon ) getPntrToComponent(0)->set( i, 1.0 ); 108 : } 109 51 : } 110 : 111 : } 112 : }