Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2011-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 : #ifndef __PLUMED_core_ActionWithVirtualAtom_h 23 : #define __PLUMED_core_ActionWithVirtualAtom_h 24 : 25 : #include "ActionAtomistic.h" 26 : #include "tools/AtomNumber.h" 27 : #include "tools/Vector.h" 28 : #include "tools/Tensor.h" 29 : #include "Atoms.h" 30 : 31 : namespace PLMD { 32 : 33 : /** 34 : \ingroup INHERIT 35 : Inherit from here if you are calculating the position of a virtual atom (eg a center of mass) 36 : */ 37 : 38 : /// Class to add a single virtual atom to the system. 39 : /// (it might be extended to add multiple virtual atoms). 40 : class ActionWithVirtualAtom: 41 : public ActionAtomistic 42 : { 43 : AtomNumber index; 44 : std::vector<Tensor> derivatives; 45 : std::vector<Tensor> boxDerivatives; 46 : std::map<AtomNumber,Tensor> gradients; 47 : void apply() override; 48 : protected: 49 : /// Set position of the virtual atom 50 : void setPosition(const Vector &); 51 : /// Set its mass 52 : void setMass(double); 53 : /// Set its charge 54 : void setCharge(double); 55 : /// Request atoms on which the calculation depends 56 : void requestAtoms(const std::vector<AtomNumber> & a); 57 : /// Set the derivatives of virtual atom coordinate wrt atoms on which it dependes 58 : void setAtomsDerivatives(const std::vector<Tensor> &d); 59 : /// Set the box derivatives. 60 : /// This should be a vector of size 3. First index corresponds 61 : /// to the components of the virtual atom. 62 : /// Notice that this routine subtract the trivial term coming from cell deformation 63 : /// since this term is already implicitly included. Indeed, if the vatom 64 : /// position is a linear function of atomic coordinates it is not necessary 65 : /// to call this function (implicit term is fine) (e.g. vatom::COM and vatom::Center). 66 : /// On the other hand if the vatom position is a non-linear function of atomic coordinates this 67 : /// should be called (see vatom::Ghost). 68 : void setBoxDerivatives(const std::vector<Tensor> &d); 69 : /// Set box derivatives automatically. 70 : /// It should be called after the settomsDerivatives has been used for all 71 : /// single atoms. 72 : /// \warning It only works for virtual atoms NOT using PBCs! 73 : /// This implies that all atoms used + the new virtual atom should be 74 : /// in the same periodic image. 75 : void setBoxDerivativesNoPbc(); 76 : public: 77 : void setGradients(); 78 : const std::map<AtomNumber,Tensor> & getGradients()const; 79 : /// Return the atom id of the corresponding virtual atom 80 : AtomNumber getIndex()const; 81 : explicit ActionWithVirtualAtom(const ActionOptions&ao); 82 : ~ActionWithVirtualAtom(); 83 : static void registerKeywords(Keywords& keys); 84 : void setGradientsIfNeeded(); 85 : }; 86 : 87 : inline 88 : AtomNumber ActionWithVirtualAtom::getIndex()const { 89 235 : return index; 90 : } 91 : 92 : inline 93 : void ActionWithVirtualAtom::setPosition(const Vector & pos) { 94 14478 : atoms.positions[index.index()]=pos; 95 : } 96 : 97 : inline 98 : void ActionWithVirtualAtom::setMass(double m) { 99 14478 : atoms.masses[index.index()]=m; 100 : } 101 : 102 : inline 103 : void ActionWithVirtualAtom::setCharge(double c) { 104 14470 : atoms.charges[index.index()]=c; 105 : } 106 : 107 : inline 108 : void ActionWithVirtualAtom::setAtomsDerivatives(const std::vector<Tensor> &d) { 109 7239 : derivatives=d; 110 : } 111 : 112 : inline 113 : const std::map<AtomNumber,Tensor> & ActionWithVirtualAtom::getGradients()const { 114 : return gradients; 115 : } 116 : 117 : } 118 : 119 : #endif