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 : #include "MultiColvarShortcuts.h"
23 : #include "core/ActionShortcut.h"
24 : #include "core/ActionRegister.h"
25 : #include "tools/Pbc.h"
26 :
27 : #include <string>
28 : #include <cmath>
29 :
30 : //+PLUMEDOC MCOLVAR PLANES
31 : /*
32 : Calculate the components of the normals to the planes containing groups of three atoms.
33 :
34 : __This shortcut action allows you to calculate the planes containing sets of three atoms and reproduces the syntax in older PLUMED versions.
35 : If you look at the example inputs below you can
36 : see how the new syntax operates. We would strongly encourage you to use the newer syntax as it is simpler and offers greater flexibility.__
37 :
38 : An example input using this shortcut is shown below:
39 :
40 : ```plumed
41 : v3: PLANES ...
42 : ATOMS1=9,10,11
43 : ATOMS2=89,90,91
44 : ATOMS3=473,474,475
45 : ATOMS4=1161,1162,1163
46 : ATOMS5=1521,1522,1523
47 : ATOMS6=1593,1594,1595
48 : ATOMS7=1601,1602,1603
49 : ATOMS8=2201,2202,2203
50 : VMEAN
51 : ...
52 : PRINT ARG=v3_vmean FILE=colvar
53 : ```
54 :
55 : As you can see if you expand the shortcut above, the input calculates the vectors perpendicular to the planes containing
56 : each group of three atoms. The mean value is then computed by adding all these three dimensional vectors together. The final
57 : value output is the norm of this mean vector. This norm is large if the orientations of the planes containing the groups of
58 : atoms are the same and small if they are not.
59 :
60 : */
61 : //+ENDPLUMEDOC
62 :
63 : namespace PLMD {
64 : namespace multicolvar {
65 :
66 : class PlaneShortcut : public ActionShortcut {
67 : private:
68 : void createVectorNormInput( const std::string& ilab, const std::string& olab, const std::string& vlab );
69 : public:
70 : static void registerKeywords( Keywords& keys );
71 : PlaneShortcut(const ActionOptions&);
72 : };
73 :
74 : PLUMED_REGISTER_ACTION(PlaneShortcut,"PLANES")
75 :
76 3 : void PlaneShortcut::registerKeywords( Keywords& keys ) {
77 3 : ActionShortcut::registerKeywords( keys );
78 3 : MultiColvarShortcuts::shortcutKeywords( keys );
79 3 : keys.add("numbered","ATOMS","the sets of atoms that you would like to calculate the planes for");
80 3 : keys.add("numbered","LOCATION","the location at which the CV is assumed to be in space");
81 6 : keys.reset_style("LOCATION","atoms");
82 3 : keys.addFlag("VMEAN",false,"calculate the norm of the mean vector.");
83 6 : keys.addOutputComponent("_vmean","VMEAN","scalar","the norm of the mean vector");
84 3 : keys.addFlag("VSUM",false,"calculate the norm of the sum of all the vectors");
85 6 : keys.addOutputComponent("_vsum","VSUM","scalar","the norm of the mean vector");
86 3 : keys.needsAction("CENTER");
87 3 : keys.needsAction("GROUP");
88 3 : keys.needsAction("PLANE");
89 3 : keys.needsAction("MEAN");
90 3 : keys.needsAction("SUM");
91 3 : keys.needsAction("COMBINE");
92 3 : keys.needsAction("CUSTOM");
93 3 : keys.setDeprecated("PLANE");
94 3 : }
95 :
96 1 : PlaneShortcut::PlaneShortcut(const ActionOptions&ao):
97 : Action(ao),
98 1 : ActionShortcut(ao) {
99 : bool vmean, vsum;
100 1 : parseFlag("VMEAN",vmean);
101 2 : parseFlag("VSUM",vsum);
102 : std::string dline;
103 1 : std::string grpstr = getShortcutLabel() + "_grp: GROUP ATOMS=";
104 1 : for(unsigned i=1;; ++i) {
105 : std::string atstring;
106 18 : parseNumbered("ATOMS",i,atstring);
107 9 : if( atstring.length()==0 ) {
108 : break;
109 : }
110 : std::string locstr;
111 16 : parseNumbered("LOCATION",i,locstr);
112 8 : if( locstr.length()==0 ) {
113 : std::string num;
114 8 : Tools::convert( i, num );
115 16 : readInputLine( getShortcutLabel() + "_vatom" + num + ": CENTER ATOMS=" + atstring );
116 8 : if( i==1 ) {
117 2 : grpstr += getShortcutLabel() + "_vatom" + num;
118 : } else {
119 14 : grpstr += "," + getShortcutLabel() + "_vatom" + num;
120 : }
121 : } else {
122 0 : if( i==1 ) {
123 : grpstr += locstr;
124 : } else {
125 0 : grpstr += "," + locstr;
126 : }
127 : }
128 : std::string num;
129 8 : Tools::convert( i, num );
130 16 : dline += " ATOMS" + num + "=" + atstring;
131 8 : }
132 1 : readInputLine( grpstr );
133 2 : readInputLine( getShortcutLabel() + ": PLANE " + dline + " " + convertInputLineToString() );
134 1 : if( vmean ) {
135 2 : readInputLine( getShortcutLabel() + "_xs: MEAN ARG=" + getShortcutLabel() + ".x PERIODIC=NO");
136 2 : readInputLine( getShortcutLabel() + "_ys: MEAN ARG=" + getShortcutLabel() + ".y PERIODIC=NO");
137 2 : readInputLine( getShortcutLabel() + "_zs: MEAN ARG=" + getShortcutLabel() + ".z PERIODIC=NO");
138 : // Now calculate the total length of the vector
139 2 : createVectorNormInput( getShortcutLabel(), getShortcutLabel() + "_vmean", "s" );
140 : }
141 1 : if( vsum ) {
142 0 : readInputLine( getShortcutLabel() + "_xz: SUM ARG=" + getShortcutLabel() + ".x PERIODIC=NO");
143 0 : readInputLine( getShortcutLabel() + "_yz: SUM ARG=" + getShortcutLabel() + ".y PERIODIC=NO");
144 0 : readInputLine( getShortcutLabel() + "_zz: SUM ARG=" + getShortcutLabel() + ".z PERIODIC=NO");
145 : // Now calculate the total length of the vector
146 0 : createVectorNormInput( getShortcutLabel(), getShortcutLabel() + "_vsum", "z" );
147 : }
148 1 : }
149 :
150 1 : void PlaneShortcut::createVectorNormInput( const std::string& ilab, const std::string& olab, const std::string& vlab ) {
151 2 : readInputLine( olab + "2: COMBINE ARG=" + ilab + "_x" + vlab + "," + ilab + "_y" + vlab + "," + ilab + "_z" + vlab + " POWERS=2,2,2 PERIODIC=NO");
152 2 : readInputLine( olab + ": CUSTOM ARG=" + olab + "2 FUNC=sqrt(x) PERIODIC=NO");
153 1 : }
154 :
155 : }
156 : }
157 :
158 :
159 :
|