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 87 : keys.addActionNameSuffix("_CALC"); 57 87 : keys.needsAction("LESS_THAN"); 58 87 : keys.needsAction("MORE_THAN"); 59 87 : keys.needsAction("GROUP"); 60 87 : keys.needsAction("BETWEEN"); 61 87 : keys.needsAction("SUM"); 62 87 : keys.needsAction("MEAN"); 63 87 : keys.needsAction("CUSTOM"); 64 87 : } 65 : 66 : template <const char* v> 67 59 : VolumeShortcut<v>::VolumeShortcut(const ActionOptions&ao): 68 : Action(ao), 69 59 : ActionShortcut(ao) { 70 59 : std::string voltype(v), mc_lab; 71 59 : parse("DATA",mc_lab); 72 : bool dosum; 73 118 : parseFlag("SUM",dosum); 74 59 : if( mc_lab.length()>0 ) { 75 12 : Group* mygrp = plumed.getActionSet().template selectWithLabel<Group*>(mc_lab); 76 12 : Group* mygrp2 = plumed.getActionSet().template selectWithLabel<Group*>(mc_lab + "_grp"); 77 12 : if( mygrp || mygrp2 ) { 78 20 : readInputLine( getShortcutLabel() + "_grp: GROUP ATOMS=" + mc_lab ); 79 : } 80 : bool domean; 81 24 : parseFlag("MEAN",domean); 82 : std::string lt_input, mt_input, bt_input; 83 12 : parse("LESS_THAN",lt_input); 84 12 : parse("MORE_THAN",mt_input); 85 24 : parse("BETWEEN",bt_input); 86 : std::string atomsd; 87 24 : parse("ATOMS",atomsd); 88 12 : if( atomsd.length()==0 ) { 89 : atomsd=mc_lab; 90 : } 91 : // Create the apprpriate volume object 92 24 : readInputLine( getShortcutLabel() + ": " + voltype + "_CALC " + convertInputLineToString() + " ATOMS=" + atomsd ); 93 : // Now create input for sums 94 12 : if( dosum || domean ) { 95 24 : readInputLine( getShortcutLabel() + "_prod: CUSTOM ARG=" + mc_lab + "," + getShortcutLabel() + " FUNC=x*y PERIODIC=NO"); 96 12 : std::string tlab = getShortcutLabel() + "_numer"; 97 12 : if( dosum ) { 98 0 : tlab = getShortcutLabel() + "_sum:"; 99 : } 100 24 : readInputLine( tlab + ": SUM ARG=" + getShortcutLabel() + "_prod PERIODIC=NO"); 101 : } 102 12 : if( domean ) { 103 : // Calculate denominator 104 24 : readInputLine( getShortcutLabel() + "_norm: SUM ARG=" + getShortcutLabel() + " PERIODIC=NO"); 105 : // And calculate final quantity which is mean of these two actions 106 12 : std::string arg1_lab = getShortcutLabel() + "_numer"; 107 12 : if( dosum ) { 108 0 : arg1_lab = getShortcutLabel() + "_sum"; 109 : } 110 24 : readInputLine( getShortcutLabel() + "_mean: CUSTOM ARG=" + arg1_lab + "," + getShortcutLabel() + "_norm FUNC=x/y PERIODIC=NO"); 111 : } 112 12 : if( lt_input.length()>0 ) { 113 : // Calculate number less than 114 14 : readInputLine( mc_lab + "_" + getShortcutLabel() + "_lt: LESS_THAN ARG=" + mc_lab + " SWITCH={" + lt_input +"}"); 115 : // And the matheval bit 116 14 : readInputLine( getShortcutLabel() + "_lt: CUSTOM ARG=" + mc_lab + "_" + getShortcutLabel() + "_lt," + getShortcutLabel() + " FUNC=x*y PERIODIC=NO"); 117 : // And the final sum 118 14 : readInputLine( getShortcutLabel() + "_lessthan: SUM ARG=" + getShortcutLabel() + "_lt PERIODIC=NO"); 119 : } 120 12 : if( mt_input.length()>0 ) { 121 : // Calculate number less than 122 0 : readInputLine( mc_lab + "_" + getShortcutLabel() + "_mt: MORE_THAN ARG=" + mc_lab + " SWITCH={" + mt_input + "}"); 123 : // And the matheval bit 124 0 : readInputLine( getShortcutLabel() + "_mt: CUSTOM ARG=" + mc_lab + "_" + getShortcutLabel() + "_mt," + getShortcutLabel() + " FUNC=x*y PERIODIC=NO"); 125 : // And the final sum 126 0 : readInputLine( getShortcutLabel() + "_morethan: SUM ARG=" + getShortcutLabel() + "_mt PERIODIC=NO"); 127 : } 128 12 : if( bt_input.length()>0 ) { 129 : // Calculate number less than 130 0 : readInputLine( mc_lab + "_" + getShortcutLabel() + "_bt: BETWEEN ARG=" + mc_lab + " SWITCH={" + bt_input +"}"); 131 : // And the matheval bit 132 0 : readInputLine( getShortcutLabel() + "_bt: CUSTOM ARG=" + mc_lab + "_" + getShortcutLabel() + "_bt," + getShortcutLabel() + " FUNC=x*y PERIODIC=NO"); 133 : // And the final sum 134 0 : readInputLine( getShortcutLabel() + "_between: SUM ARG=" + getShortcutLabel() + "_bt PERIODIC=NO"); 135 : } 136 47 : } else if( dosum ) { 137 20 : readInputLine( getShortcutLabel() + "_vols: " + voltype + "_CALC " + convertInputLineToString() ); 138 20 : readInputLine( getShortcutLabel() + ": SUM ARG=" + getShortcutLabel() + "_vols PERIODIC=NO"); 139 : } else { 140 74 : readInputLine( getShortcutLabel() + ": " + voltype + "_CALC " + convertInputLineToString() ); 141 : } 142 59 : } 143 : 144 : } 145 : } 146 : #endif