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();
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 182 : return index;
90 : }
91 :
92 : inline
93 : void ActionWithVirtualAtom::setPosition(const Vector & pos) {
94 6824 : atoms.positions[index.index()]=pos;
95 : }
96 :
97 : inline
98 : void ActionWithVirtualAtom::setMass(double m) {
99 6824 : atoms.masses[index.index()]=m;
100 : }
101 :
102 : inline
103 : void ActionWithVirtualAtom::setCharge(double c) {
104 6816 : atoms.charges[index.index()]=c;
105 : }
106 :
107 : inline
108 : void ActionWithVirtualAtom::setAtomsDerivatives(const std::vector<Tensor> &d) {
109 3412 : derivatives=d;
110 : }
111 :
112 : inline
113 : const std::map<AtomNumber,Tensor> & ActionWithVirtualAtom::getGradients()const {
114 : return gradients;
115 : }
116 :
117 : }
118 :
119 : #endif
|