Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2011-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 : #ifndef __PLUMED_core_ActionWithVirtualAtom_h 23 : #define __PLUMED_core_ActionWithVirtualAtom_h 24 : 25 : #include "ActionAtomistic.h" 26 : #include "ActionWithValue.h" 27 : #include "tools/AtomNumber.h" 28 : #include "tools/Vector.h" 29 : #include "tools/Tensor.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 : public ActionWithValue 43 : { 44 : protected: 45 : /// Set position of the virtual atom 46 : void setPosition(const Vector &); 47 : /// Set its mass 48 : void setMass(double); 49 : /// Set its charge 50 : void setCharge(double); 51 : /// Request the atoms on which the calculation demands 52 : void requestAtoms(const std::vector<AtomNumber> & a); 53 : /// Set the derivatives of virtual atom coordinate wrt atoms on which it dependes 54 : void setAtomsDerivatives(const std::vector<Tensor> &d); 55 : /// Set the box derivatives. 56 : /// This should be a vector of size 3. First index corresponds 57 : /// to the components of the virtual atom. 58 : /// Notice that this routine subtract the trivial term coming from cell deformation 59 : /// since this term is already implicitly included. Indeed, if the vatom 60 : /// position is a linear function of atomic coordinates it is not necessary 61 : /// to call this function (implicit term is fine) (e.g. vatom::COM and vatom::Center). 62 : /// On the other hand if the vatom position is a non-linear function of atomic coordinates this 63 : /// should be called (see vatom::Ghost). 64 : void setBoxDerivatives(const std::vector<Tensor> &d); 65 : /// Set box derivatives automatically. 66 : /// It should be called after the settomsDerivatives has been used for all 67 : /// single atoms. 68 : /// \warning It only works for virtual atoms NOT using PBCs! 69 : /// This implies that all atoms used + the new virtual atom should be 70 : /// in the same periodic image. 71 : void setBoxDerivativesNoPbc(); 72 : public: 73 : /// Return the atom id of the corresponding virtual atom 74 : AtomNumber getIndex()const; 75 : explicit ActionWithVirtualAtom(const ActionOptions&ao); 76 : static void registerKeywords(Keywords& keys); 77 : virtual unsigned getNumberOfDerivatives(); 78 : virtual void apply(); 79 6746861 : ActionWithVirtualAtom* castToActionWithVirtualAtom() noexcept final { return this; } 80 : }; 81 : 82 : inline 83 645611 : unsigned ActionWithVirtualAtom::getNumberOfDerivatives() { 84 645611 : return 3*getNumberOfAtoms()+9; 85 : } 86 : 87 : inline 88 35094 : void ActionWithVirtualAtom::setPosition(const Vector & pos) { 89 140376 : for(unsigned i=0; i<3; ++i) getPntrToComponent(i)->set(pos[i]); 90 35094 : } 91 : 92 : inline 93 27098 : void ActionWithVirtualAtom::setMass(double m) { 94 27098 : getPntrToComponent(3)->set(m); 95 27098 : } 96 : 97 : inline 98 27098 : void ActionWithVirtualAtom::setCharge(double c) { 99 27098 : getPntrToComponent(4)->set(c); 100 27098 : } 101 : 102 : inline 103 35094 : void ActionWithVirtualAtom::setAtomsDerivatives(const std::vector<Tensor> &d) { 104 : unsigned jj=0; 105 35094 : Value* xval=getPntrToComponent(0); 106 35094 : Value* yval=getPntrToComponent(1); 107 35094 : Value* zval=getPntrToComponent(2); 108 419563 : for(unsigned j=0; j<getNumberOfAtoms(); ++j) { 109 1537876 : for(unsigned k=0; k<3; ++k) { 110 1153407 : xval->setDerivative( jj, d[j][k][0] ); 111 1153407 : yval->setDerivative( jj, d[j][k][1] ); 112 1153407 : zval->setDerivative( jj, d[j][k][2] ); 113 : jj++; 114 : } 115 : } 116 35094 : } 117 : 118 : } 119 : 120 : #endif