Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2011-2018 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_ActionAtomistic_h
23 : #define __PLUMED_core_ActionAtomistic_h
24 :
25 : #include "Action.h"
26 : #include "tools/Tensor.h"
27 : #include "Atoms.h"
28 : #include "tools/Pbc.h"
29 : #include <vector>
30 : #include <set>
31 :
32 : namespace PLMD {
33 :
34 : class Pbc;
35 : class PDB;
36 :
37 : /// \ingroup MULTIINHERIT
38 : /// Action used to create objects that access the positions of the atoms from the MD code
39 : class ActionAtomistic :
40 : virtual public Action
41 : {
42 :
43 : std::vector<AtomNumber> indexes; // the set of needed atoms
44 : std::set<AtomNumber> unique;
45 : std::vector<Vector> positions; // positions of the needed atoms
46 : double energy;
47 : Pbc& pbc;
48 : Tensor virial;
49 : std::vector<double> masses;
50 : bool chargesWereSet;
51 : std::vector<double> charges;
52 :
53 : std::vector<Vector> forces; // forces on the needed atoms
54 : double forceOnEnergy;
55 :
56 : bool lockRequestAtoms; // forbid changes to request atoms
57 :
58 : bool donotretrieve;
59 : bool donotforce;
60 :
61 : protected:
62 : Atoms& atoms;
63 :
64 : public:
65 : /// Request an array of atoms.
66 : /// This method is used to ask for a list of atoms. Atoms
67 : /// should be asked for by number. If this routine is called
68 : /// during the simulation, atoms will be available at the next step
69 : /// MAYBE WE HAVE TO FIND SOMETHING MORE CLEAR FOR DYNAMIC
70 : /// LISTS OF ATOMS
71 : void requestAtoms(const std::vector<AtomNumber> & a);
72 : /// Get position of i-th atom (access by relative index)
73 : const Vector & getPosition(int)const;
74 : /// Get position of i-th atom (access by absolute AtomNumber).
75 : /// With direct access to the global atom array
76 : const Vector & getPosition(AtomNumber)const;
77 : /// Get modifiable position of i-th atom (access by absolute AtomNumber).
78 : /// Should be used by action that need to modify the stored atomic coordinates
79 : Vector & modifyPosition(AtomNumber);
80 : /// Get total number of atoms, including virtual ones.
81 : /// Can be used to make a loop on modifyPosition or getPosition(AtomNumber)
82 : unsigned getTotAtoms()const;
83 : /// Get modifiable force of i-th atom (access by absolute AtomNumber).
84 : /// \warning Should be used by action that need to modify the stored atomic forces.
85 : /// This should be used with great care since the plumed core does
86 : /// not usually keep all these forces up to date. In particular,
87 : /// if an action require this, one should during constructor
88 : /// call allowToAccessGlobalForces().
89 : /// Notice that for efficiency reason plumed does not check if this is done!
90 : Vector & modifyGlobalForce(AtomNumber);
91 : /// Get modifiable virial
92 : /// Should be used by action that need to modify the stored virial
93 : Tensor & modifyGlobalVirial();
94 : /// Get modifiable PBC
95 : /// Should be used by action that need to modify the stored box
96 : Pbc & modifyGlobalPbc();
97 : /// Get box shape
98 : const Tensor & getBox()const;
99 : /// Get the array of all positions
100 : const std::vector<Vector> & getPositions()const;
101 : /// Get energy
102 : const double & getEnergy()const;
103 : /// Get mass of i-th atom
104 : double getMass(int i)const;
105 : /// Get charge of i-th atom
106 : double getCharge(int i)const;
107 : /// Get a reference to forces array
108 : std::vector<Vector> & modifyForces();
109 : /// Get a reference to virial array
110 : Tensor & modifyVirial();
111 : /// Get a reference to force on energy
112 : double & modifyForceOnEnergy();
113 : /// Get number of available atoms
114 4174709143 : unsigned getNumberOfAtoms()const {return indexes.size();}
115 : /// Compute the pbc distance between two positions
116 : Vector pbcDistance(const Vector&,const Vector&)const;
117 : /// Applies PBCs to a seriens of positions or distances
118 : void pbcApply(std::vector<Vector>& dlist, unsigned max_index=0) const;
119 : /// Get the vector of absolute indexes
120 : virtual const std::vector<AtomNumber> & getAbsoluteIndexes()const;
121 : /// Get the absolute index of an atom
122 : AtomNumber getAbsoluteIndex(int i)const;
123 : /// Parse a list of atoms without a numbered keyword
124 : void parseAtomList(const std::string&key,std::vector<AtomNumber> &t);
125 : /// Parse an list of atom with a numbred keyword
126 : void parseAtomList(const std::string&key,const int num, std::vector<AtomNumber> &t);
127 : /// Convert a set of read in strings into an atom list (this is used in parseAtomList)
128 : void interpretAtomList( std::vector<std::string>& strings, std::vector<AtomNumber> &t);
129 : /// Change the box shape
130 : void changeBox( const Tensor& newbox );
131 : /// Get reference to Pbc
132 : const Pbc & getPbc() const;
133 : /// Add the forces to the atoms
134 : void setForcesOnAtoms( const std::vector<double>& forcesToApply, unsigned ind=0 );
135 : /// Skip atom retrieval - use with care.
136 : /// If this function is called during initialization, then atoms are
137 : /// not going to be retrieved. Can be used for optimization. Notice that
138 : /// calling getPosition(int) in an Action where DoNotRetrieve() was called might
139 : /// lead to undefined behavior.
140 15 : void doNotRetrieve() {donotretrieve=true;}
141 : /// Skip atom forces - use with care.
142 : /// If this function is called during initialization, then forces are
143 : /// not going to be propagated. Can be used for optimization.
144 7 : void doNotForce() {donotforce=true;}
145 : /// Make atoms whole, assuming they are in the proper order
146 : void makeWhole();
147 : /// Allow calls to modifyGlobalForce()
148 8 : void allowToAccessGlobalForces() {atoms.zeroallforces=true;}
149 : public:
150 :
151 : // virtual functions:
152 :
153 : explicit ActionAtomistic(const ActionOptions&ao);
154 : ~ActionAtomistic();
155 :
156 : static void registerKeywords( Keywords& keys );
157 :
158 : void clearOutputForces();
159 :
160 : /// N.B. only pass an ActionWithValue to this routine if you know exactly what you
161 : /// are doing. The default will be correct for the vast majority of cases
162 : virtual void calculateNumericalDerivatives( ActionWithValue* a=NULL );
163 : /// Numerical derivative routine to use when using Actions that inherit from BOTH
164 : /// ActionWithArguments and ActionAtomistic
165 : void calculateAtomicNumericalDerivatives( ActionWithValue* a, const unsigned& startnum );
166 :
167 : virtual void retrieveAtoms();
168 : void applyForces();
169 : void lockRequests();
170 : void unlockRequests();
171 : const std::set<AtomNumber> & getUnique()const;
172 : /// Read in an input file containing atom positions and calculate the action for the atomic
173 : /// configuration therin
174 : void readAtomsFromPDB( const PDB& pdb );
175 : };
176 :
177 : inline
178 74719362 : const Vector & ActionAtomistic::getPosition(int i)const {
179 74719362 : return positions[i];
180 : }
181 :
182 : inline
183 4244 : const Vector & ActionAtomistic::getPosition(AtomNumber i)const {
184 4244 : return atoms.positions[i.index()];
185 : }
186 :
187 : inline
188 21952 : Vector & ActionAtomistic::modifyPosition(AtomNumber i) {
189 21952 : return atoms.positions[i.index()];
190 : }
191 :
192 : inline
193 14638 : Vector & ActionAtomistic::modifyGlobalForce(AtomNumber i) {
194 14638 : return atoms.forces[i.index()];
195 : }
196 :
197 : inline
198 113 : Tensor & ActionAtomistic::modifyGlobalVirial() {
199 113 : return atoms.virial;
200 : }
201 :
202 : inline
203 61136 : double ActionAtomistic::getMass(int i)const {
204 61136 : return masses[i];
205 : }
206 :
207 : inline
208 18361 : double ActionAtomistic::getCharge(int i) const {
209 18361 : if( !chargesWereSet ) error("charges were not passed to plumed");
210 18361 : return charges[i];
211 : }
212 :
213 : inline
214 1282 : const std::vector<AtomNumber> & ActionAtomistic::getAbsoluteIndexes()const {
215 1282 : return indexes;
216 : }
217 :
218 : inline
219 11544493 : AtomNumber ActionAtomistic::getAbsoluteIndex(int i)const {
220 11544493 : return indexes[i];
221 : }
222 :
223 : inline
224 749347 : const std::vector<Vector> & ActionAtomistic::getPositions()const {
225 749347 : return positions;
226 : }
227 :
228 : inline
229 50 : const double & ActionAtomistic::getEnergy()const {
230 50 : return energy;
231 : }
232 :
233 : inline
234 13442 : const Tensor & ActionAtomistic::getBox()const {
235 13442 : return pbc.getBox();
236 : }
237 :
238 : inline
239 70429 : std::vector<Vector> & ActionAtomistic::modifyForces() {
240 70429 : return forces;
241 : }
242 :
243 : inline
244 46824 : Tensor & ActionAtomistic::modifyVirial() {
245 46824 : return virial;
246 : }
247 :
248 : inline
249 50 : double & ActionAtomistic::modifyForceOnEnergy() {
250 50 : return forceOnEnergy;
251 : }
252 :
253 : inline
254 246606 : const Pbc & ActionAtomistic::getPbc() const {
255 246606 : return pbc;
256 : }
257 :
258 : inline
259 56252 : void ActionAtomistic::lockRequests() {
260 56252 : lockRequestAtoms=true;
261 56252 : }
262 :
263 : inline
264 56252 : void ActionAtomistic::unlockRequests() {
265 56252 : lockRequestAtoms=false;
266 56252 : }
267 :
268 : inline
269 56666 : const std::set<AtomNumber> & ActionAtomistic::getUnique()const {
270 56666 : return unique;
271 : }
272 :
273 : inline
274 28830 : unsigned ActionAtomistic::getTotAtoms()const {
275 28830 : return atoms.positions.size();
276 : }
277 :
278 : inline
279 65 : Pbc & ActionAtomistic::modifyGlobalPbc() {
280 65 : return atoms.pbc;
281 : }
282 :
283 :
284 :
285 : }
286 :
287 : #endif
|