Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2016-2023 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/ActionShortcut.h" 23 : #include "core/ActionRegister.h" 24 : #include "MultiColvarShortcuts.h" 25 : 26 : //+PLUMEDOC COLVAR XANGLES 27 : /* 28 : Calculate the angle between an arbitrary vector and the positive x direction 29 : 30 : __As you can see if you expand the inputs below, you can achieve what this shortcut action does by using [DISTANCE](DISTANCE.md) together with [CUSTOM](CUSTOM.md), 31 : [BETWEEN](BETWEEN.md), [LESS_THAN](LESS_THAN.md), [SUM](SUM.md) and [MEAN](MEAN.md). We strongly encourage you to use these actions instead as using them will provide 32 : you with a clearer understanding of the equations you are using.__ 33 : 34 : The following input tells plumed to calculate the angles between the x-axis and the vector connecting atom 3 to atom 5 and between the x-axis 35 : and the vector connecting atom 1 to atom 2. The minimum of these two quantities is then output 36 : 37 : ```plumed 38 : d1: XANGLES ATOMS1=3,5 ATOMS2=1,2 MIN={BETA=0.1} 39 : PRINT ARG=d1.min FILE=colvar 40 : ``` 41 : 42 : Notice that this command is a shortcut. You can thus learn more about how to use PLUMED by examining the expanded version of the input above. 43 : 44 : */ 45 : //+ENDPLUMEDOC 46 : 47 : //+PLUMEDOC COLVAR YANGLES 48 : /* 49 : Calculate the angle between an arbitrary vector and the positive y direction 50 : 51 : __As you can see if you expand the inputs below, you can achieve what this shortcut action does by using [DISTANCE](DISTANCE.md) together with [CUSTOM](CUSTOM.md), 52 : [BETWEEN](BETWEEN.md), [LESS_THAN](LESS_THAN.md), [SUM](SUM.md) and [MEAN](MEAN.md). We strongly encourage you to use these actions instead as using them will provide 53 : you with a clearer understanding of the equations you are using.__ 54 : 55 : The following input tells plumed to calculate the angles between the y-axis and the vector connecting atom 3 to atom 5 and between the y-axis 56 : and the vector connecting atom 1 to atom 2. The minimum of these two quantities is then output 57 : 58 : ```plumed 59 : d1: YANGLES ATOMS1=3,5 ATOMS2=1,2 MIN={BETA=0.1} 60 : PRINT ARG=d1.min FILE=colvar 61 : ``` 62 : 63 : Notice that this command is a shortcut. You can thus learn more about how to use PLUMED by examining the expanded version of the input above. 64 : 65 : */ 66 : //+ENDPLUMEDOC 67 : 68 : //+PLUMEDOC COLVAR ZANGLES 69 : /* 70 : Calculate the angle between an arbitrary vector and the positive z direction 71 : 72 : __As you can see if you expand the inputs below, you can achieve what this shortcut action does by using [DISTANCE](DISTANCE.md) together with [CUSTOM](CUSTOM.md), 73 : [BETWEEN](BETWEEN.md), [LESS_THAN](LESS_THAN.md), [SUM](SUM.md) and [MEAN](MEAN.md). We strongly encourage you to use these actions instead as using them will provide 74 : you with a clearer understanding of the equations you are using.__ 75 : 76 : The following input tells plumed to calculate the angles between the z-axis and the vector connecting atom 3 to atom 5 and between the z-axis 77 : and the vector connecting atom 1 to atom 2. The minimum of these two quantities is then output 78 : 79 : ```plumed 80 : d1: ZANGLES ATOMS1=3,5 ATOMS2=1,2 MIN={BETA=0.1} 81 : PRINT ARG=d1.min FILE=colvar 82 : ``` 83 : 84 : Notice that this command is a shortcut. You can thus learn more about how to use PLUMED by examining the expanded version of the input above. 85 : 86 : */ 87 : //+ENDPLUMEDOC 88 : 89 : 90 : namespace PLMD { 91 : namespace multicolvar { 92 : 93 : class XAngle : public ActionShortcut { 94 : public: 95 : static void registerKeywords(Keywords& keys); 96 : explicit XAngle(const ActionOptions&); 97 : }; 98 : 99 : PLUMED_REGISTER_ACTION(XAngle,"XANGLES") 100 : PLUMED_REGISTER_ACTION(XAngle,"YANGLES") 101 : PLUMED_REGISTER_ACTION(XAngle,"ZANGLES") 102 : 103 9 : void XAngle::registerKeywords(Keywords& keys) { 104 9 : ActionShortcut::registerKeywords( keys ); 105 9 : keys.add("numbered","ATOMS","the pairs of atoms that you would like to calculate the angles for"); 106 18 : keys.reset_style("ATOMS","atoms"); 107 9 : MultiColvarShortcuts::shortcutKeywords( keys ); 108 9 : keys.needsAction("DISTANCE"); 109 9 : keys.needsAction("COMBINE"); 110 9 : keys.needsAction("CUSTOM"); 111 9 : keys.setDeprecated("DISTANCE"); 112 9 : } 113 : 114 1 : XAngle::XAngle(const ActionOptions& ao): 115 : Action(ao), 116 1 : ActionShortcut(ao) { 117 : // Create distances 118 1 : std::string dline = getShortcutLabel() + "_dists: DISTANCE COMPONENTS"; 119 1 : for(unsigned i=1;; ++i) { 120 : std::string atstring; 121 6 : parseNumbered("ATOMS",i,atstring); 122 3 : if( atstring.length()==0 ) { 123 : break; 124 : } 125 : std::string num; 126 2 : Tools::convert( i, num ); 127 4 : dline += " ATOMS" + num + "=" + atstring; 128 2 : } 129 1 : readInputLine( dline ); 130 : // Normalize the vectors 131 2 : readInputLine( getShortcutLabel() + "_norm2: COMBINE ARG=" + getShortcutLabel() + "_dists.x" + "," + getShortcutLabel() + "_dists.y," + getShortcutLabel() + "_dists.z POWERS=2,2,2 PERIODIC=NO"); 132 2 : readInputLine( getShortcutLabel() + "_norm: CUSTOM ARG=" + getShortcutLabel() + "_norm2 FUNC=sqrt(x) PERIODIC=NO"); 133 2 : readInputLine( getShortcutLabel() + "_norm_x: CUSTOM ARG=" + getShortcutLabel() + "_dists.x," + getShortcutLabel() + "_norm FUNC=x/y PERIODIC=NO"); 134 2 : readInputLine( getShortcutLabel() + "_norm_y: CUSTOM ARG=" + getShortcutLabel() + "_dists.y," + getShortcutLabel() + "_norm FUNC=x/y PERIODIC=NO"); 135 2 : readInputLine( getShortcutLabel() + "_norm_z: CUSTOM ARG=" + getShortcutLabel() + "_dists.z," + getShortcutLabel() + "_norm FUNC=x/y PERIODIC=NO"); 136 : // Now compute the angles with matheval 137 1 : if( getName()=="XANGLES" ) { 138 2 : readInputLine( getShortcutLabel() + "_ang: CUSTOM FUNC=acos(x) PERIODIC=NO ARG=" + getShortcutLabel() + "_norm_x"); 139 : } 140 1 : if( getName()=="YANGLES" ) { 141 0 : readInputLine( getShortcutLabel() + "_ang: CUSTOM FUNC=acos(x) PERIODIC=NO ARG=" + getShortcutLabel() + "_norm_y"); 142 : } 143 1 : if( getName()=="ZANGLES" ) { 144 0 : readInputLine( getShortcutLabel() + "_ang: CUSTOM FUNC=acos(x) PERIODIC=NO ARG=" + getShortcutLabel() + "_norm_z"); 145 : } 146 : // Add shortcuts to label 147 2 : MultiColvarShortcuts::expandFunctions( getShortcutLabel(), getShortcutLabel() + "_ang", "", this ); 148 1 : } 149 : 150 : } 151 : }