Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2012-2020 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 "MultiColvarBase.h"
23 : #include "AtomValuePack.h"
24 : #include "core/ActionRegister.h"
25 :
26 : #include <string>
27 : #include <cmath>
28 :
29 : using namespace std;
30 :
31 : namespace PLMD {
32 : namespace multicolvar {
33 :
34 : //+PLUMEDOC MCOLVAR XDISTANCES
35 : /*
36 : Calculate the x components of the vectors connecting one or many pairs of atoms.
37 : You can then calculate functions of the distribution of values such as the minimum, the number less than a certain quantity and so on.
38 :
39 : \par Examples
40 :
41 : The following input tells plumed to calculate the x-component of the vector connecting atom 3 to atom 5 and
42 : the x-component of the vector connecting atom 1 to atom 2. The minimum of these two quantities is then
43 : printed
44 : \plumedfile
45 : d1: XDISTANCES ATOMS1=3,5 ATOMS2=1,2 MIN={BETA=0.1}
46 : PRINT ARG=d1.min
47 : \endplumedfile
48 : (See also \ref PRINT).
49 :
50 :
51 : The following input tells plumed to calculate the x-component of the vector connecting atom 3 to atom 5 and
52 : the x-component of the vector connecting atom 1 to atom 2. The number of values that are
53 : less than 0.1nm is then printed to a file.
54 : \plumedfile
55 : d1: XDISTANCES ATOMS1=3,5 ATOMS2=1,2 LESS_THAN={RATIONAL R_0=0.1}
56 : PRINT ARG=d1.lessthan
57 : \endplumedfile
58 : (See also \ref PRINT \ref switchingfunction).
59 :
60 : The following input tells plumed to calculate the x-components of all the distinct vectors that can be created
61 : between atoms 1, 2 and 3 (i.e. the vectors between atoms 1 and 2, atoms 1 and 3 and atoms 2 and 3).
62 : The average of these quantities is then calculated.
63 : \plumedfile
64 : d1: XDISTANCES GROUP=1-3 MEAN
65 : PRINT ARG=d1.mean
66 : \endplumedfile
67 : (See also \ref PRINT)
68 :
69 : The following input tells plumed to calculate all the vectors connecting the the atoms in GROUPA to the atoms in GROUPB.
70 : In other words the vector between atoms 1 and 2 and the vector between atoms 1 and 3. The number of values
71 : more than 0.1 is then printed to a file.
72 : \plumedfile
73 : d1: XDISTANCES GROUPA=1 GROUPB=2,3 MORE_THAN={RATIONAL R_0=0.1}
74 : PRINT ARG=d1.morethan
75 : \endplumedfile
76 : (See also \ref PRINT \ref switchingfunction)
77 : */
78 : //+ENDPLUMEDOC
79 :
80 : //+PLUMEDOC MCOLVAR YDISTANCES
81 : /*
82 : Calculate the y components of the vectors connecting one or many pairs of atoms.
83 : You can then calculate functions of the distribution of values such as the minimum, the number less than a certain quantity and so on.
84 :
85 : \par Examples
86 :
87 : The following input tells plumed to calculate the y-component of the vector connecting atom 3 to atom 5 and
88 : the y-component of the vector connecting atom 1 to atom 2. The minimum of these two quantities is then
89 : printed
90 : \plumedfile
91 : d1: YDISTANCES ATOMS1=3,5 ATOMS2=1,2 MIN={BETA=0.1}
92 : PRINT ARG=d1.min
93 : \endplumedfile
94 : (See also \ref PRINT).
95 :
96 :
97 : The following input tells plumed to calculate the y-component of the vector connecting atom 3 to atom 5 and
98 : the y-component of the vector connecting atom 1 to atom 2. The number of values that are
99 : less than 0.1nm is then printed to a file.
100 : \plumedfile
101 : d1: YDISTANCES ATOMS1=3,5 ATOMS2=1,2 LESS_THAN={RATIONAL R_0=0.1}
102 : PRINT ARG=d1.lessthan
103 : \endplumedfile
104 : (See also \ref PRINT \ref switchingfunction).
105 :
106 : The following input tells plumed to calculate the y-components of all the distinct vectors that can be created
107 : between atoms 1, 2 and 3 (i.e. the vectors between atoms 1 and 2, atoms 1 and 3 and atoms 2 and 3).
108 : The average of these quantities is then calculated.
109 : \plumedfile
110 : d1: YDISTANCES GROUP=1-3 MEAN
111 : PRINT ARG=d1.mean
112 : \endplumedfile
113 : (See also \ref PRINT)
114 :
115 : The following input tells plumed to calculate all the vectors connecting the the atoms in GROUPA to the atoms in GROUPB.
116 : In other words the vector between atoms 1 and 2 and the vector between atoms 1 and 3. The number of values
117 : more than 0.1 is then printed to a file.
118 : \plumedfile
119 : d1: YDISTANCES GROUPA=1 GROUPB=2,3 MORE_THAN={RATIONAL R_0=0.1}
120 : PRINT ARG=d1.morethan
121 : \endplumedfile
122 : (See also \ref PRINT \ref switchingfunction)
123 :
124 : */
125 : //+ENDPLUMEDOC
126 :
127 : //+PLUMEDOC MCOLVAR ZDISTANCES
128 : /*
129 : Calculate the z components of the vectors connecting one or many pairs of atoms.
130 : You can then calculate functions of the distribution of values such as the minimum, the number less than a certain quantity and so on.
131 :
132 : \par Examples
133 :
134 : The following input tells plumed to calculate the z-component of the vector connecting atom 3 to atom 5 and
135 : the z-component of the vector connecting atom 1 to atom 2. The minimum of these two quantities is then
136 : printed
137 : \plumedfile
138 : d1: ZDISTANCES ATOMS1=3,5 ATOMS2=1,2 MIN={BETA=0.1}
139 : PRINT ARG=d1.min
140 : \endplumedfile
141 : (See also \ref PRINT).
142 :
143 :
144 : The following input tells plumed to calculate the z-component of the vector connecting atom 3 to atom 5 and
145 : the z-component of the vector connecting atom 1 to atom 2. The number of values that are
146 : less than 0.1nm is then printed to a file.
147 : \plumedfile
148 : d1: ZDISTANCES ATOMS1=3,5 ATOMS2=1,2 LESS_THAN={RATIONAL R_0=0.1}
149 : PRINT ARG=d1.lessthan
150 : \endplumedfile
151 : (See also \ref PRINT \ref switchingfunction).
152 :
153 : The following input tells plumed to calculate the z-components of all the distinct vectors that can be created
154 : between atoms 1, 2 and 3 (i.e. the vectors between atoms 1 and 2, atoms 1 and 3 and atoms 2 and 3).
155 : The average of these quantities is then calculated.
156 : \plumedfile
157 : d1: ZDISTANCES GROUP=1-3 MEAN
158 : PRINT ARG=d1.mean
159 : \endplumedfile
160 : (See also \ref PRINT)
161 :
162 : The following input tells plumed to calculate all the vectors connecting the the atoms in GROUPA to the atoms in GROUPB.
163 : In other words the vector between atoms 1 and 2 and the vector between atoms 1 and 3. The number of values
164 : more than 0.1 is then printed to a file.
165 : \plumedfile
166 : d1: ZDISTANCES GROUPA=1 GROUPB=2,3 MORE_THAN={RATIONAL R_0=0.1}
167 : PRINT ARG=d1.morethan
168 : \endplumedfile
169 : (See also \ref PRINT \ref switchingfunction)
170 :
171 : */
172 : //+ENDPLUMEDOC
173 :
174 :
175 0 : class XDistances : public MultiColvarBase {
176 : private:
177 : unsigned myc;
178 : public:
179 : static void registerKeywords( Keywords& keys );
180 : explicit XDistances(const ActionOptions&);
181 : // active methods:
182 : virtual double compute( const unsigned& tindex, AtomValuePack& myatoms ) const ;
183 : /// Returns the number of coordinates of the field
184 0 : bool isPeriodic() { return false; }
185 : };
186 :
187 7356 : PLUMED_REGISTER_ACTION(XDistances,"XDISTANCES")
188 7356 : PLUMED_REGISTER_ACTION(XDistances,"YDISTANCES")
189 7356 : PLUMED_REGISTER_ACTION(XDistances,"ZDISTANCES")
190 :
191 3 : void XDistances::registerKeywords( Keywords& keys ) {
192 3 : MultiColvarBase::registerKeywords( keys );
193 9 : keys.use("MAX"); keys.use("ALT_MIN");
194 12 : keys.use("MEAN"); keys.use("MIN"); keys.use("LESS_THAN");
195 9 : keys.use("LOWEST"); keys.use("HIGHEST");
196 15 : keys.use("MORE_THAN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
197 12 : keys.add("numbered","ATOMS","the atoms involved in each of the distances you wish to calculate. "
198 : "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one distance will be "
199 : "calculated for each ATOM keyword you specify (all ATOM keywords should "
200 : "specify the indices of two atoms). The eventual number of quantities calculated by this "
201 : "action will depend on what functions of the distribution you choose to calculate.");
202 9 : keys.reset_style("ATOMS","atoms");
203 12 : keys.add("atoms-1","GROUP","Calculate the distance between each distinct pair of atoms in the group");
204 12 : keys.add("atoms-2","GROUPA","Calculate the distances between all the atoms in GROUPA and all "
205 : "the atoms in GROUPB. This must be used in conjunction with GROUPB.");
206 12 : keys.add("atoms-2","GROUPB","Calculate the distances between all the atoms in GROUPA and all the atoms "
207 : "in GROUPB. This must be used in conjunction with GROUPA.");
208 3 : }
209 :
210 0 : XDistances::XDistances(const ActionOptions&ao):
211 : Action(ao),
212 0 : MultiColvarBase(ao)
213 : {
214 0 : if( getName().find("X")!=std::string::npos) myc=0;
215 0 : else if( getName().find("Y")!=std::string::npos) myc=1;
216 0 : else if( getName().find("Z")!=std::string::npos) myc=2;
217 0 : else plumed_error();
218 :
219 : // Read in the atoms
220 : std::vector<AtomNumber> all_atoms;
221 0 : readTwoGroups( "GROUP", "GROUPA", "GROUPB", all_atoms );
222 0 : if( atom_lab.size()==0 ) readAtomsLikeKeyword( "ATOMS", 2, all_atoms );
223 0 : setupMultiColvarBase( all_atoms );
224 : // And check everything has been read in correctly
225 0 : checkRead();
226 0 : }
227 :
228 0 : double XDistances::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
229 0 : Vector distance;
230 0 : distance=getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
231 0 : const double value=distance[myc];
232 :
233 0 : Vector myvec; myvec.zero();
234 : // And finish the calculation
235 0 : myvec[myc]=+1; addAtomDerivatives( 1, 1, myvec, myatoms );
236 0 : myvec[myc]=-1; addAtomDerivatives( 1, 0, myvec, myatoms );
237 0 : myatoms.addBoxDerivatives( 1, Tensor(distance,myvec) );
238 0 : return value;
239 : }
240 :
241 : }
242 5517 : }
243 :
|