Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2015-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 XYDISTANCES 33 : /* 34 : Calculate distance between a pair of atoms neglecting the z-component. 35 : 36 : You can then calculate functions of the distribution of values such as the minimum, the number less than a certain quantity and so on. 37 : 38 : \par Examples 39 : 40 : The following input tells plumed to calculate the projection of the length of the vector connecting atom 3 41 : to atom 5 projected in the xy-plane and the projection of the length of the vector 42 : the vector connecting atom 1 to atom 2 in the xy-plane. The minimum of these two quantities is then 43 : printed 44 : \plumedfile 45 : d1: XYDISTANCES 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 : //+ENDPLUMEDOC 52 : 53 : //+PLUMEDOC MCOLVAR XZDISTANCES 54 : /* 55 : Calculate distance between a pair of atoms neglecting the y-component. 56 : 57 : You can then calculate functions of the distribution of 58 : values such as the minimum, the number less than a certain quantity and so on. 59 : 60 : \par Examples 61 : 62 : The following input tells plumed to calculate the projection of the length of the vector connecting atom 3 63 : to atom 5 projected in the xz-plane and the projection of the length of the vector 64 : the vector connecting atom 1 to atom 2 in the xz-plane. The minimum of these two quantities is then 65 : printed 66 : \plumedfile 67 : d1: XZDISTANCES ATOMS1=3,5 ATOMS2=1,2 MIN={BETA=0.1} 68 : PRINT ARG=d1.min 69 : \endplumedfile 70 : (See also \ref PRINT). 71 : 72 : */ 73 : //+ENDPLUMEDOC 74 : 75 : //+PLUMEDOC MCOLVAR YZDISTANCES 76 : /* 77 : Calculate distance between a pair of atoms neglecting the x-component. 78 : 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 : d1: YZDISTANCES 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 : //+ENDPLUMEDOC 96 : 97 : 98 : 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 : double compute( const unsigned& tindex, AtomValuePack& myatoms ) const override; 106 : /// Returns the number of coordinates of the field 107 0 : bool isPeriodic() override { return false; } 108 : }; 109 : 110 10419 : PLUMED_REGISTER_ACTION(XYDistances,"XYDISTANCES") 111 10419 : PLUMED_REGISTER_ACTION(XYDistances,"XZDISTANCES") 112 10419 : PLUMED_REGISTER_ACTION(XYDistances,"YZDISTANCES") 113 : 114 3 : void XYDistances::registerKeywords( Keywords& keys ) { 115 3 : MultiColvarBase::registerKeywords( keys ); 116 6 : keys.use("MAX"); keys.use("ALT_MIN"); 117 15 : keys.use("MEAN"); keys.use("MIN"); keys.use("LESS_THAN"); keys.use("LOWEST"); keys.use("HIGHEST"); 118 12 : keys.use("MORE_THAN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS"); 119 6 : 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 indices 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 6 : keys.reset_style("ATOMS","atoms"); 125 6 : keys.add("atoms-1","GROUP","Calculate the distance between each distinct pair of atoms in the group"); 126 6 : 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 conjunction with GROUPB."); 128 6 : 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 conjunction 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=std::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 : } 169 :