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 87 : keys.add("hidden","IS_SHORTCUT","hidden keyword to tell if actions are shortcuts so that example generator can provide expansions of shortcuts"); 45 87 : 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 87 : 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","scalar","the number of cvs in the region of interest that are less than a certain threshold"); 48 87 : 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","scalar","the number of cvs in the region of interest that are more than a certain threshold"); 50 87 : 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","scalar","the number of cvs in the region of interest that are within a certain range"); 52 87 : keys.addFlag("SUM",false,"calculate the sum of all the quantities."); 53 174 : keys.addOutputComponent("sum","SUM","scalar","the sum of all the colvars weighted by the function that determines if we are in the region"); 54 87 : keys.addFlag("MEAN",false,"calculate the average value of the colvar inside the region of interest"); 55 174 : keys.addOutputComponent("mean","MEAN","scalar","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 174 : keys.setValueDescription("scalar","sum of values of input CVs in regin of interest"); 65 87 : } 66 : 67 : template <const char* v> 68 59 : VolumeShortcut<v>::VolumeShortcut(const ActionOptions&ao): 69 : Action(ao), 70 59 : ActionShortcut(ao) { 71 59 : std::string voltype(v), mc_lab; 72 59 : parse("DATA",mc_lab); 73 : bool dosum; 74 118 : parseFlag("SUM",dosum); 75 59 : if( mc_lab.length()>0 ) { 76 12 : Group* mygrp = plumed.getActionSet().template selectWithLabel<Group*>(mc_lab); 77 12 : Group* mygrp2 = plumed.getActionSet().template selectWithLabel<Group*>(mc_lab + "_grp"); 78 12 : if( mygrp || mygrp2 ) { 79 20 : readInputLine( getShortcutLabel() + "_grp: GROUP ATOMS=" + mc_lab ); 80 : } 81 : bool domean; 82 24 : parseFlag("MEAN",domean); 83 : std::string lt_input, mt_input, bt_input; 84 12 : parse("LESS_THAN",lt_input); 85 12 : parse("MORE_THAN",mt_input); 86 24 : parse("BETWEEN",bt_input); 87 : std::string atomsd; 88 24 : parse("ATOMS",atomsd); 89 12 : if( atomsd.length()==0 ) { 90 : atomsd=mc_lab; 91 : } 92 : // Create the apprpriate volume object 93 24 : readInputLine( getShortcutLabel() + ": " + voltype + "_CALC " + convertInputLineToString() + " ATOMS=" + atomsd ); 94 : // Now create input for sums 95 12 : if( dosum || domean ) { 96 24 : readInputLine( getShortcutLabel() + "_prod: CUSTOM ARG=" + mc_lab + "," + getShortcutLabel() + " FUNC=x*y PERIODIC=NO"); 97 12 : std::string tlab = getShortcutLabel() + "_numer"; 98 12 : if( dosum ) { 99 0 : tlab = getShortcutLabel() + "_sum:"; 100 : } 101 24 : readInputLine( tlab + ": SUM ARG=" + getShortcutLabel() + "_prod PERIODIC=NO"); 102 : } 103 12 : if( domean ) { 104 : // Calculate denominator 105 24 : readInputLine( getShortcutLabel() + "_norm: SUM ARG=" + getShortcutLabel() + " PERIODIC=NO"); 106 : // And calculate final quantity which is mean of these two actions 107 12 : std::string arg1_lab = getShortcutLabel() + "_numer"; 108 12 : if( dosum ) { 109 0 : arg1_lab = getShortcutLabel() + "_sum"; 110 : } 111 24 : readInputLine( getShortcutLabel() + "_mean: CUSTOM ARG=" + arg1_lab + "," + getShortcutLabel() + "_norm FUNC=x/y PERIODIC=NO"); 112 : } 113 12 : if( lt_input.length()>0 ) { 114 : // Calculate number less than 115 14 : readInputLine( mc_lab + "_" + getShortcutLabel() + "_lt: LESS_THAN ARG=" + mc_lab + " SWITCH={" + lt_input +"}"); 116 : // And the matheval bit 117 14 : readInputLine( getShortcutLabel() + "_lt: CUSTOM ARG=" + mc_lab + "_" + getShortcutLabel() + "_lt," + getShortcutLabel() + " FUNC=x*y PERIODIC=NO"); 118 : // And the final sum 119 14 : readInputLine( getShortcutLabel() + "_lessthan: SUM ARG=" + getShortcutLabel() + "_lt PERIODIC=NO"); 120 : } 121 12 : if( mt_input.length()>0 ) { 122 : // Calculate number less than 123 0 : readInputLine( mc_lab + "_" + getShortcutLabel() + "_mt: MORE_THAN ARG=" + mc_lab + " SWITCH={" + mt_input + "}"); 124 : // And the matheval bit 125 0 : readInputLine( getShortcutLabel() + "_mt: CUSTOM ARG=" + mc_lab + "_" + getShortcutLabel() + "_mt," + getShortcutLabel() + " FUNC=x*y PERIODIC=NO"); 126 : // And the final sum 127 0 : readInputLine( getShortcutLabel() + "_morethan: SUM ARG=" + getShortcutLabel() + "_mt PERIODIC=NO"); 128 : } 129 12 : if( bt_input.length()>0 ) { 130 : // Calculate number less than 131 0 : readInputLine( mc_lab + "_" + getShortcutLabel() + "_bt: BETWEEN ARG=" + mc_lab + " SWITCH={" + bt_input +"}"); 132 : // And the matheval bit 133 0 : readInputLine( getShortcutLabel() + "_bt: CUSTOM ARG=" + mc_lab + "_" + getShortcutLabel() + "_bt," + getShortcutLabel() + " FUNC=x*y PERIODIC=NO"); 134 : // And the final sum 135 0 : readInputLine( getShortcutLabel() + "_between: SUM ARG=" + getShortcutLabel() + "_bt PERIODIC=NO"); 136 : } 137 47 : } else if( dosum ) { 138 20 : readInputLine( getShortcutLabel() + "_vols: " + voltype + "_CALC " + convertInputLineToString() ); 139 20 : readInputLine( getShortcutLabel() + ": SUM ARG=" + getShortcutLabel() + "_vols PERIODIC=NO"); 140 : } else { 141 74 : readInputLine( getShortcutLabel() + ": " + voltype + "_CALC " + convertInputLineToString() ); 142 : } 143 59 : } 144 : 145 : } 146 : } 147 : #endif