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