Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2011-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 : #ifndef __PLUMED_volumes_VolumeShortcut_h 23 : #define __PLUMED_volumes_VolumeShortcut_h 24 : 25 : #include "core/ActionShortcut.h" 26 : #include "core/ActionRegister.h" 27 : #include "core/PlumedMain.h" 28 : #include "core/ActionSet.h" 29 : #include "core/Group.h" 30 : 31 : namespace PLMD { 32 : namespace volumes { 33 : 34 : template <const char* v> 35 : class VolumeShortcut : public ActionShortcut { 36 : public: 37 : static void registerKeywords( Keywords& keys ); 38 : VolumeShortcut(const ActionOptions&ao); 39 : }; 40 : 41 : template <const char* v> 42 87 : void VolumeShortcut<v>::registerKeywords( Keywords& keys ) { 43 174 : actionRegister().getKeywords( std::string(v) + "_CALC", keys ); 44 174 : keys.add("hidden","IS_SHORTCUT","hidden keyword to tell if actions are shortcuts so that example generator can provide expansions of shortcuts"); 45 174 : keys.add("optional","DATA","the label of an action that calculates multicolvars. Weighted sums based on the location of the colvars calculated by this action will be calcualted"); 46 174 : keys.add("optional","LESS_THAN","calcualte the number of colvars that are inside the region of interest and that are less than a certain threshold"); 47 174 : keys.addOutputComponent("lessthan","LESS_THAN","the number of cvs in the region of interest that are less than a certain threshold"); 48 174 : keys.add("optional","MORE_THAN","calcualte the number of colvars that are inside the region of interest and that are greater that a certain threshold"); 49 174 : keys.addOutputComponent("morethan","MORE_THAN","the number of cvs in the region of interest that are more than a certain threshold"); 50 174 : keys.add("optional","BETWEEN","calculate the number of colvars that are inside the region of interest and that have a CV value that is between a particular set of bounds"); 51 174 : keys.addOutputComponent("between","BETWEEN","the number of cvs in the region of interest that are within a certain range"); 52 174 : keys.addFlag("SUM",false,"calculate the sum of all the quantities."); 53 174 : keys.addOutputComponent("sum","SUM","the sum of all the colvars weighted by the function that determines if we are in the region"); 54 174 : keys.addFlag("MEAN",false,"calculate the average value of the colvar inside the region of interest"); 55 174 : keys.addOutputComponent("mean","MEAN","the average values of the colvar in the region of interest"); 56 348 : keys.addActionNameSuffix("_CALC"); keys.needsAction("LESS_THAN"); keys.needsAction("MORE_THAN"); keys.needsAction("GROUP"); 57 348 : keys.needsAction("BETWEEN"); keys.needsAction("SUM"); keys.needsAction("MEAN"); keys.needsAction("CUSTOM"); 58 87 : } 59 : 60 : template <const char* v> 61 59 : VolumeShortcut<v>::VolumeShortcut(const ActionOptions&ao): 62 : Action(ao), 63 59 : ActionShortcut(ao) 64 : { 65 177 : std::string voltype(v), mc_lab; parse("DATA",mc_lab); bool dosum; parseFlag("SUM",dosum); 66 59 : if( mc_lab.length()>0 ) { 67 12 : Group* mygrp = plumed.getActionSet().template selectWithLabel<Group*>(mc_lab); 68 12 : Group* mygrp2 = plumed.getActionSet().template selectWithLabel<Group*>(mc_lab + "_grp"); 69 22 : if( mygrp || mygrp2 ) readInputLine( getShortcutLabel() + "_grp: GROUP ATOMS=" + mc_lab ); 70 24 : bool domean; parseFlag("MEAN",domean); std::string lt_input, mt_input, bt_input; 71 48 : parse("LESS_THAN",lt_input); parse("MORE_THAN",mt_input); parse("BETWEEN",bt_input); 72 24 : std::string atomsd; parse("ATOMS",atomsd); if( atomsd.length()==0 ) atomsd=mc_lab; 73 : // Create the apprpriate volume object 74 24 : readInputLine( getShortcutLabel() + ": " + voltype + "_CALC " + convertInputLineToString() + " ATOMS=" + atomsd ); 75 : // Now create input for sums 76 12 : if( dosum || domean ) { 77 24 : readInputLine( getShortcutLabel() + "_prod: CUSTOM ARG=" + mc_lab + "," + getShortcutLabel() + " FUNC=x*y PERIODIC=NO"); 78 12 : std::string tlab = getShortcutLabel() + "_numer"; if( dosum ) tlab = getShortcutLabel() + "_sum:"; 79 24 : readInputLine( tlab + ": SUM ARG=" + getShortcutLabel() + "_prod PERIODIC=NO"); 80 : } 81 12 : if( domean ) { 82 : // Calculate denominator 83 24 : readInputLine( getShortcutLabel() + "_norm: SUM ARG=" + getShortcutLabel() + " PERIODIC=NO"); 84 : // And calculate final quantity which is mean of these two actions 85 12 : std::string arg1_lab = getShortcutLabel() + "_numer"; if( dosum ) arg1_lab = getShortcutLabel() + "_sum"; 86 24 : readInputLine( getShortcutLabel() + "_mean: CUSTOM ARG=" + arg1_lab + "," + getShortcutLabel() + "_norm FUNC=x/y PERIODIC=NO"); 87 : } 88 12 : if( lt_input.length()>0 ) { 89 : // Calculate number less than 90 14 : readInputLine( mc_lab + "_" + getShortcutLabel() + "_lt: LESS_THAN ARG=" + mc_lab + " SWITCH={" + lt_input +"}"); 91 : // And the matheval bit 92 14 : readInputLine( getShortcutLabel() + "_lt: CUSTOM ARG=" + mc_lab + "_" + getShortcutLabel() + "_lt," + getShortcutLabel() + " FUNC=x*y PERIODIC=NO"); 93 : // And the final sum 94 14 : readInputLine( getShortcutLabel() + "_lessthan: SUM ARG=" + getShortcutLabel() + "_lt PERIODIC=NO"); 95 : } 96 12 : if( mt_input.length()>0 ) { 97 : // Calculate number less than 98 0 : readInputLine( mc_lab + "_" + getShortcutLabel() + "_mt: MORE_THAN ARG=" + mc_lab + " SWITCH={" + mt_input + "}"); 99 : // And the matheval bit 100 0 : readInputLine( getShortcutLabel() + "_mt: CUSTOM ARG=" + mc_lab + "_" + getShortcutLabel() + "_mt," + getShortcutLabel() + " FUNC=x*y PERIODIC=NO"); 101 : // And the final sum 102 0 : readInputLine( getShortcutLabel() + "_morethan: SUM ARG=" + getShortcutLabel() + "_mt PERIODIC=NO"); 103 : } 104 12 : if( bt_input.length()>0 ) { 105 : // Calculate number less than 106 0 : readInputLine( mc_lab + "_" + getShortcutLabel() + "_bt: BETWEEN ARG=" + mc_lab + " SWITCH={" + bt_input +"}"); 107 : // And the matheval bit 108 0 : readInputLine( getShortcutLabel() + "_bt: CUSTOM ARG=" + mc_lab + "_" + getShortcutLabel() + "_bt," + getShortcutLabel() + " FUNC=x*y PERIODIC=NO"); 109 : // And the final sum 110 0 : readInputLine( getShortcutLabel() + "_between: SUM ARG=" + getShortcutLabel() + "_bt PERIODIC=NO"); 111 : } 112 47 : } else if( dosum ) { 113 20 : readInputLine( getShortcutLabel() + "_vols: " + voltype + "_CALC " + convertInputLineToString() ); 114 20 : readInputLine( getShortcutLabel() + ": SUM ARG=" + getShortcutLabel() + "_vols PERIODIC=NO"); 115 : } else { 116 74 : readInputLine( getShortcutLabel() + ": " + voltype + "_CALC " + convertInputLineToString() ); 117 : } 118 59 : } 119 : 120 : } 121 : } 122 : #endif