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