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 "ActionWithVirtualAtom.h" 23 : #include "ActionRegister.h" 24 : #include "tools/Vector.h" 25 : #include "tools/Exception.h" 26 : 27 : namespace PLMD { 28 : namespace vatom { 29 : 30 : //+PLUMEDOC VATOM FIXEDATOM 31 : /* 32 : Add a virtual atom in a fixed position. 33 : 34 : This action creates a virtual atom at a fixed position. 35 : The coordinates can be specified in Cartesian components (by default) 36 : or in scaled coordinates (SCALED_COMPONENTS). 37 : It is also possible to assign a predefined charge or mass to the atom. 38 : 39 : \attention 40 : Similar to \ref POSITION this variable is not invariant for translation 41 : of the system. Adding a force on it can create serious troubles. 42 : 43 : Notice that the distance between two atoms created 44 : using FIXEDATOM is invariant for translation. 45 : Additionally, if one first align atoms to a reference using \ref FIT_TO_TEMPLATE, 46 : then it is safe to add further fixed atoms without breaking translational invariance. 47 : 48 : \par Examples 49 : 50 : The following input instructs plumed to compute the angle between 51 : distance of atoms 15 and 20 and the z axis and keeping it close to zero. 52 : \plumedfile 53 : a: FIXEDATOM AT=0,0,0 54 : b: FIXEDATOM AT=0,0,1 55 : an: ANGLE ATOMS=a,b,15,20 56 : RESTRAINT ARG=an AT=0.0 KAPPA=100.0 57 : \endplumedfile 58 : 59 : The following input instructs plumed to align a protein to a template 60 : and to then compute the distance between one of the atoms in the protein and the point 61 : (10,20,30). 62 : \plumedfile 63 : FIT_TO_TEMPLATE STRIDE=1 REFERENCE=ref.pdb TYPE=SIMPLE 64 : a: FIXEDATOM AT=10,20,30 65 : d: DISTANCE ATOMS=a,20 66 : PRINT ARG=d FILE=colvar 67 : \endplumedfile 68 : 69 : The reference structure to align to is provided in a pdb file called ref.pdb as shown below: 70 : 71 : \auxfile{ref.pdb} 72 : ATOM 8 HT3 ALA 2 -1.480 -1.560 1.212 1.00 1.00 DIA H 73 : ATOM 9 CAY ALA 2 -0.096 2.144 -0.669 1.00 1.00 DIA C 74 : ATOM 10 HY1 ALA 2 0.871 2.385 -0.588 1.00 1.00 DIA H 75 : ATOM 12 HY3 ALA 2 -0.520 2.679 -1.400 1.00 1.00 DIA H 76 : ATOM 14 OY ALA 2 -1.139 0.931 -0.973 1.00 1.00 DIA O 77 : END 78 : \endauxfile 79 : 80 : 81 : */ 82 : //+ENDPLUMEDOC 83 : 84 : 85 : class FixedAtom: 86 : public ActionWithVirtualAtom { 87 : Vector coord; 88 : double mass,charge; 89 : bool scaled_components; 90 : public: 91 : explicit FixedAtom(const ActionOptions&ao); 92 : void calculate() override; 93 : static void registerKeywords( Keywords& keys ); 94 : }; 95 : 96 13803 : PLUMED_REGISTER_ACTION(FixedAtom,"FIXEDATOM") 97 : 98 13 : void FixedAtom::registerKeywords(Keywords& keys) { 99 13 : ActionWithVirtualAtom::registerKeywords(keys); 100 26 : keys.add("compulsory","AT","coordinates of the virtual atom"); 101 26 : keys.add("compulsory","SET_MASS","1","mass of the virtual atom"); 102 26 : keys.add("compulsory","SET_CHARGE","0","charge of the virtual atom"); 103 26 : keys.addFlag("SCALED_COMPONENTS",false,"use scaled components"); 104 13 : } 105 : 106 9 : FixedAtom::FixedAtom(const ActionOptions&ao): 107 : Action(ao), 108 9 : ActionWithVirtualAtom(ao) { 109 : std::vector<AtomNumber> atoms; 110 18 : parseAtomList("ATOMS",atoms); 111 9 : if(atoms.size()!=0) { 112 0 : error("ATOMS should be empty"); 113 : } 114 : 115 18 : parseFlag("SCALED_COMPONENTS",scaled_components); 116 : 117 : std::vector<double> at; 118 18 : parseVector("AT",at); 119 9 : if(at.size()!=3) { 120 0 : error("AT should be a list of three real numbers"); 121 : } 122 : 123 9 : parse("SET_MASS",mass); 124 18 : parse("SET_CHARGE",charge); 125 : 126 9 : coord[0]=at[0]; 127 9 : coord[1]=at[1]; 128 9 : coord[2]=at[2]; 129 : 130 9 : checkRead(); 131 9 : log<<" AT position "<<coord[0]<<" "<<coord[1]<<" "<<coord[2]<<"\n"; 132 9 : if(scaled_components) { 133 1 : log<<" position is in scaled components\n"; 134 : } 135 9 : } 136 : 137 603 : void FixedAtom::calculate() { 138 603 : std::vector<Tensor> deriv(getNumberOfAtoms()); 139 603 : if(scaled_components) { 140 5 : setPosition(getPbc().scaledToReal(coord)); 141 : } else { 142 : setPosition(coord); 143 : } 144 603 : setMass(mass); 145 603 : setCharge(charge); 146 : setAtomsDerivatives(deriv); 147 : // Virial contribution 148 603 : if(!scaled_components) { 149 598 : setBoxDerivativesNoPbc(); 150 : } 151 : // notice that with scaled components there is no additional virial contribution 152 603 : } 153 : 154 : } 155 : }