Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2015-2019 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 XYDISTANCES
35 : /*
36 : Calculate distance between a pair of atoms neglecting the z-component.
37 : You can then calculate functions of the distribution of
38 : values such as the minimum, the number less than a certain quantity and so on.
39 :
40 : \par Examples
41 :
42 : The following input tells plumed to calculate the projection of the length of the vector connecting atom 3
43 : to atom 5 projected in the xy-plane and the projection of the length of the vector
44 : the vector connecting atom 1 to atom 2 in the xy-plane. The minimum of these two quantities is then
45 : printed
46 : \plumedfile
47 : XYDISTANCES ATOMS1=3,5 ATOMS2=1,2 MIN={BETA=0.1} LABEL=d1
48 : PRINT ARG=d1.min
49 : \endplumedfile
50 : (See also \ref PRINT).
51 :
52 : */
53 : //+ENDPLUMEDOC
54 :
55 : //+PLUMEDOC MCOLVAR XZDISTANCES
56 : /*
57 : Calculate distance between a pair of atoms neglecting the y-component.
58 : You can then calculate functions of the distribution of
59 : values such as the minimum, the number less than a certain quantity and so on.
60 :
61 : \par Examples
62 :
63 : The following input tells plumed to calculate the projection of the length of the vector connecting atom 3
64 : to atom 5 projected in the xz-plane and the projection of the length of the vector
65 : the vector connecting atom 1 to atom 2 in the xz-plane. The minimum of these two quantities is then
66 : printed
67 : \plumedfile
68 : XZDISTANCES ATOMS1=3,5 ATOMS2=1,2 MIN={BETA=0.1} LABEL=d1
69 : PRINT ARG=d1.min
70 : \endplumedfile
71 : (See also \ref PRINT).
72 :
73 : */
74 : //+ENDPLUMEDOC
75 :
76 : //+PLUMEDOC MCOLVAR YZDISTANCES
77 : /*
78 : Calculate distance between a pair of atoms neglecting the x-component.
79 : You can then calculate functions of the distribution of
80 : values such as the minimum, the number less than a certain quantity and so on.
81 :
82 : \par Examples
83 :
84 : The following input tells plumed to calculate the projection of the length of the vector connecting atom 3
85 : to atom 5 in the yz-plane and the projection of the length of the vector
86 : the vector connecting atom 1 to atom 2 in the yz-plane. The minimum of these two quantities is then
87 : printed
88 : \plumedfile
89 : YZDISTANCES ATOMS1=3,5 ATOMS2=1,2 MIN={BETA=0.1} LABEL=d1
90 : PRINT ARG=d1.min
91 : \endplumedfile
92 : (See also \ref PRINT).
93 :
94 : */
95 : //+ENDPLUMEDOC
96 :
97 :
98 0 : class XYDistances : public MultiColvarBase {
99 : private:
100 : unsigned myc1, myc2;
101 : public:
102 : static void registerKeywords( Keywords& keys );
103 : explicit XYDistances(const ActionOptions&);
104 : // active methods:
105 : virtual double compute( const unsigned& tindex, AtomValuePack& myatoms ) const ;
106 : /// Returns the number of coordinates of the field
107 0 : bool isPeriodic() { return false; }
108 : };
109 :
110 6452 : PLUMED_REGISTER_ACTION(XYDistances,"XYDISTANCES")
111 6452 : PLUMED_REGISTER_ACTION(XYDistances,"XZDISTANCES")
112 6452 : PLUMED_REGISTER_ACTION(XYDistances,"YZDISTANCES")
113 :
114 3 : void XYDistances::registerKeywords( Keywords& keys ) {
115 3 : MultiColvarBase::registerKeywords( keys );
116 9 : keys.use("MAX"); keys.use("ALT_MIN");
117 18 : keys.use("MEAN"); keys.use("MIN"); keys.use("LESS_THAN"); keys.use("LOWEST"); keys.use("HIGHEST");
118 15 : keys.use("MORE_THAN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
119 12 : keys.add("numbered","ATOMS","the atoms involved in each of the distances you wish to calculate. "
120 : "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one distance will be "
121 : "calculated for each ATOM keyword you specify (all ATOM keywords should "
122 : "specify the incides of two atoms). The eventual number of quantities calculated by this "
123 : "action will depend on what functions of the distribution you choose to calculate.");
124 9 : keys.reset_style("ATOMS","atoms");
125 12 : keys.add("atoms-1","GROUP","Calculate the distance between each distinct pair of atoms in the group");
126 12 : keys.add("atoms-2","GROUPA","Calculate the distances between all the atoms in GROUPA and all "
127 : "the atoms in GROUPB. This must be used in conjuction with GROUPB.");
128 12 : keys.add("atoms-2","GROUPB","Calculate the distances between all the atoms in GROUPA and all the atoms "
129 : "in GROUPB. This must be used in conjuction with GROUPA.");
130 3 : }
131 :
132 0 : XYDistances::XYDistances(const ActionOptions&ao):
133 : Action(ao),
134 0 : MultiColvarBase(ao)
135 : {
136 0 : if( getName().find("XY")!=std::string::npos) {
137 0 : myc1=0; myc2=1;
138 0 : } else if( getName().find("XZ")!=std::string::npos) {
139 0 : myc1=0; myc2=2;
140 0 : } else if( getName().find("YZ")!=std::string::npos) {
141 0 : myc1=1; myc2=2;
142 0 : } else plumed_error();
143 :
144 : // Read in the atoms
145 : std::vector<AtomNumber> all_atoms;
146 0 : readTwoGroups( "GROUP", "GROUPA", "GROUPB", all_atoms );
147 0 : if( atom_lab.size()==0 ) readAtomsLikeKeyword( "ATOMS", 2, all_atoms );
148 0 : setupMultiColvarBase( all_atoms );
149 : // And check everything has been read in correctly
150 0 : checkRead();
151 0 : }
152 :
153 0 : double XYDistances::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
154 0 : Vector distance;
155 0 : distance=getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
156 0 : const double value=sqrt(distance[myc1]*distance[myc1] + distance[myc2]*distance[myc2] );
157 0 : const double invvalue=1.0/value;
158 :
159 0 : Vector myvec; myvec.zero();
160 : // And finish the calculation
161 0 : myvec[myc1]=+invvalue*distance[myc1]; myvec[myc2]=+invvalue*distance[myc2]; addAtomDerivatives( 1, 1, myvec, myatoms );
162 0 : myvec[myc1]=-invvalue*distance[myc1]; myvec[myc2]=-invvalue*distance[myc2]; addAtomDerivatives( 1, 0, myvec, myatoms );
163 0 : myatoms.addBoxDerivatives( 1, Tensor(distance,myvec) );
164 0 : return value;
165 : }
166 :
167 : }
168 4839 : }
169 :
|