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 : keys.remove("ARG"); 69 57 : ActionWithValue::registerKeywords( keys ); 70 57 : keys.remove("NUMERICAL_DERIVATIVES"); 71 114 : keys.add("compulsory","CLUSTERS","the label of the action that does the clustering"); 72 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."); 73 114 : keys.addFlag("LOWMEM",false,"this flag does nothing and is present only to ensure back-compatibility"); 74 : // keys.add("hidden","FROM_PROPERTIES","indicates that this is created from CLUSTER_PROPERTIES shortcut"); 75 57 : keys.setValueDescription("vector with elements that are one if the atom of interest is part of the required cluster and zero otherwise"); 76 57 : } 77 : 78 29 : ClusterWeights::ClusterWeights(const ActionOptions&ao): 79 : Action(ao), 80 : ActionWithArguments(ao), 81 29 : ActionWithValue(ao) { 82 : bool lowmem; 83 29 : parseFlag("LOWMEM",lowmem); 84 29 : if( lowmem ) { 85 0 : warning("LOWMEM flag is deprecated and is no longer required for this action"); 86 : } 87 : // Read in the clustering object 88 : std::vector<Value*> clusters; 89 58 : parseArgumentList("CLUSTERS",clusters); 90 29 : if( clusters.size()!=1 ) { 91 0 : error("should pass only one matrix to clustering base"); 92 : } 93 29 : ClusteringBase* cc = dynamic_cast<ClusteringBase*>( clusters[0]->getPntrToAction() ); 94 29 : if( !cc ) { 95 0 : error("input to CLUSTERS keyword should be a clustering action"); 96 : } 97 : // Request the arguments 98 29 : requestArguments( clusters ); 99 : // Now create the value 100 29 : std::vector<unsigned> shape(1); 101 29 : shape[0]=clusters[0]->getShape()[0]; 102 29 : addValue( shape ); 103 29 : setNotPeriodic(); 104 29 : getPntrToComponent(0)->buildDataStore(); 105 : // Find out which cluster we want 106 29 : parse("CLUSTER",clustr); 107 29 : if( clustr<1 ) { 108 0 : error("cannot look for a cluster larger than the largest cluster"); 109 : } 110 29 : if( clustr>clusters[0]->getShape()[0] ) { 111 0 : error("cluster selected is invalid - too few atoms in system"); 112 : } 113 29 : log.printf(" atoms in %dth largest cluster calculated by %s are equal to one \n",clustr, cc->getLabel().c_str() ); 114 29 : } 115 : 116 24 : unsigned ClusterWeights::getNumberOfDerivatives() { 117 24 : return 0; 118 : } 119 : 120 51 : void ClusterWeights::calculate() { 121 51 : plumed_assert( getPntrToArgument(0)->valueHasBeenSet() ); 122 36627 : for(unsigned i=0; i<getPntrToArgument(0)->getShape()[0]; ++i) { 123 36576 : if( fabs(getPntrToArgument(0)->get(i)-clustr)<epsilon ) { 124 9826 : getPntrToComponent(0)->set( i, 1.0 ); 125 : } 126 : } 127 51 : } 128 : 129 : } 130 : }