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