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_Atoms_h
23 : #define __PLUMED_core_Atoms_h
24 :
25 : #include "tools/Communicator.h"
26 : #include "tools/Tensor.h"
27 : #include "tools/Units.h"
28 : #include "tools/Exception.h"
29 : #include "tools/AtomNumber.h"
30 : #include <vector>
31 : #include <set>
32 : #include <map>
33 : #include <string>
34 :
35 : namespace PLMD {
36 :
37 : class MDAtomsBase;
38 : class PlumedMain;
39 : class ActionAtomistic;
40 : class ActionWithVirtualAtom;
41 : class Pbc;
42 :
43 : /// Class containing atom related quantities from the MD code.
44 : /// IT IS STILL UNDOCUMENTED. IT PROBABLY NEEDS A STRONG CLEANUP
45 : class Atoms
46 : {
47 : friend class ActionAtomistic;
48 : friend class ActionWithVirtualAtom;
49 : int natoms;
50 : std::set<AtomNumber> unique;
51 : std::vector<unsigned> uniq_index;
52 : /// Map global indexes to local indexes
53 : /// E.g. g2l[i] is the position of atom i in the array passed from the MD engine.
54 : /// Called "global to local" since originally it was used to map global indexes to local
55 : /// ones used in domain decomposition. However, it is now also used for the NAMD-like
56 : /// interface, where only a small number of atoms is passed to plumed.
57 : std::vector<int> g2l;
58 : std::vector<Vector> positions;
59 : std::vector<Vector> forces;
60 : std::vector<double> masses;
61 : std::vector<double> charges;
62 : std::vector<ActionWithVirtualAtom*> virtualAtomsActions;
63 : Tensor box;
64 : Pbc& pbc;
65 : Tensor virial;
66 : // this is the energy set by each processor:
67 : double md_energy;
68 : // this is the summed energy:
69 : double energy;
70 :
71 : bool dataCanBeSet;
72 : bool collectEnergy;
73 : bool energyHasBeenSet;
74 : unsigned positionsHaveBeenSet;
75 : bool massesHaveBeenSet;
76 : bool chargesHaveBeenSet;
77 : bool boxHasBeenSet;
78 : unsigned forcesHaveBeenSet;
79 : bool virialHasBeenSet;
80 : bool massAndChargeOK;
81 : unsigned shuffledAtoms;
82 :
83 : std::map<std::string,std::vector<AtomNumber> > groups;
84 :
85 : void resizeVectors(unsigned);
86 :
87 : std::vector<int> fullList;
88 :
89 : MDAtomsBase* mdatoms;
90 :
91 : PlumedMain & plumed;
92 :
93 : Units MDUnits;
94 : Units units;
95 :
96 : bool naturalUnits;
97 : bool MDnaturalUnits;
98 :
99 : double timestep;
100 : double forceOnEnergy;
101 :
102 : /// if set to true, all the forces in the global array are zeroes
103 : /// at every step. It should not be necessary in general, but it is
104 : /// for actions accessing to modifyGlobalForce() (e.g. FIT_TO_TEMPLATE).
105 : bool zeroallforces;
106 :
107 : double kbT;
108 :
109 : std::vector<ActionAtomistic*> actions;
110 : std::vector<int> gatindex;
111 :
112 : bool asyncSent;
113 : bool atomsNeeded;
114 :
115 4466 : class DomainDecomposition:
116 : public Communicator
117 : {
118 : public:
119 : bool on;
120 : bool async;
121 :
122 : std::vector<Communicator::Request> mpi_request_positions;
123 : std::vector<Communicator::Request> mpi_request_index;
124 :
125 : std::vector<double> positionsToBeSent;
126 : std::vector<double> positionsToBeReceived;
127 : std::vector<int> indexToBeSent;
128 : std::vector<int> indexToBeReceived;
129 102253 : operator bool() const {return on;}
130 2233 : DomainDecomposition():
131 2233 : on(false), async(false)
132 2233 : {}
133 : void enable(Communicator& c);
134 : };
135 :
136 : DomainDecomposition dd;
137 : long int ddStep; //last step in which dd happened
138 :
139 : void share(const std::set<AtomNumber>&);
140 :
141 : public:
142 :
143 : explicit Atoms(PlumedMain&plumed);
144 : ~Atoms();
145 :
146 : void init();
147 :
148 : void share();
149 : void shareAll();
150 : void wait();
151 : void updateForces();
152 :
153 : void setRealPrecision(int);
154 : int getRealPrecision()const;
155 :
156 : void setTimeStep(void*);
157 : double getTimeStep()const;
158 :
159 : void setKbT(void*);
160 : double getKbT()const;
161 :
162 : void setNatoms(int);
163 : const int & getNatoms()const;
164 :
165 : const long int& getDdStep()const;
166 : const std::vector<int>& getGatindex()const;
167 : const Pbc& getPbc()const;
168 : void getLocalMasses(std::vector<double>&);
169 : void getLocalPositions(std::vector<Vector>&);
170 : void getLocalForces(std::vector<Vector>&);
171 : void getLocalMDForces(std::vector<Vector>&);
172 : const Tensor& getVirial()const;
173 :
174 3987 : void setCollectEnergy(bool b) { collectEnergy=b; }
175 :
176 : void setDomainDecomposition(Communicator&);
177 : void setAtomsGatindex(int*,bool);
178 : void setAtomsContiguous(int);
179 : void setAtomsNlocal(int);
180 :
181 : void startStep();
182 : void setEnergy(void*);
183 : void setBox(void*);
184 : void setVirial(void*);
185 : void setPositions(void*);
186 : void setPositions(void*,int);
187 : void setForces(void*);
188 : void setForces(void*,int);
189 : void setMasses(void*);
190 : void setCharges(void*);
191 : bool chargesWereSet() const ;
192 : bool boxWasSet() const ;
193 :
194 : void MD2double(const void*m,double&d)const;
195 : void double2MD(const double&d,void*m)const;
196 :
197 : void createFullList(int*);
198 : void getFullList(int**);
199 : void clearFullList();
200 :
201 : void add(ActionAtomistic*);
202 : void remove(ActionAtomistic*);
203 :
204 3987 : double getEnergy()const {plumed_assert(collectEnergy && energyHasBeenSet); return energy;}
205 :
206 0 : bool isEnergyNeeded()const {return collectEnergy;}
207 :
208 37 : void setMDEnergyUnits(double d) {MDUnits.setEnergy(d);}
209 512 : void setMDLengthUnits(double d) {MDUnits.setLength(d);}
210 0 : void setMDTimeUnits(double d) {MDUnits.setTime(d);}
211 512 : void setMDChargeUnits(double d) {MDUnits.setCharge(d);}
212 512 : void setMDMassUnits(double d) {MDUnits.setMass(d);}
213 : const Units& getMDUnits() {return MDUnits;}
214 13 : void setUnits(const Units&u) {units=u;}
215 : const Units& getUnits() {return units;}
216 : void updateUnits();
217 :
218 : AtomNumber addVirtualAtom(ActionWithVirtualAtom*);
219 : void removeVirtualAtom(ActionWithVirtualAtom*);
220 : ActionWithVirtualAtom* getVirtualAtomsAction(AtomNumber)const;
221 : bool isVirtualAtom(AtomNumber)const;
222 : void insertGroup(const std::string&name,const std::vector<AtomNumber>&a);
223 : void removeGroup(const std::string&name);
224 : void writeBinary(std::ostream&)const;
225 : void readBinary(std::istream&);
226 : double getKBoltzmann()const;
227 : double getMDKBoltzmann()const;
228 : bool usingNaturalUnits()const;
229 13 : void setNaturalUnits(bool n) {naturalUnits=n;}
230 0 : void setMDNaturalUnits(bool n) {MDnaturalUnits=n;}
231 : };
232 :
233 : inline
234 : const int & Atoms::getNatoms()const {
235 : return natoms;
236 : }
237 :
238 : inline
239 : const long int& Atoms::getDdStep()const {
240 : return ddStep;
241 : }
242 :
243 : inline
244 : const std::vector<int>& Atoms::getGatindex()const {
245 9 : return gatindex;
246 : }
247 :
248 : inline
249 : const Pbc& Atoms::getPbc()const {
250 1350 : return pbc;
251 : }
252 :
253 : inline
254 : bool Atoms::isVirtualAtom(AtomNumber i)const {
255 618508 : return i.index()>=(unsigned) getNatoms();
256 : }
257 :
258 : inline
259 : ActionWithVirtualAtom* Atoms::getVirtualAtomsAction(AtomNumber i)const {
260 386 : return virtualAtomsActions[i.index()-getNatoms()];
261 : }
262 :
263 : inline
264 : bool Atoms::usingNaturalUnits() const {
265 1775 : return naturalUnits || MDnaturalUnits;
266 : }
267 :
268 : inline
269 : bool Atoms::chargesWereSet() const {
270 95052 : return chargesHaveBeenSet;
271 : }
272 :
273 : inline
274 : bool Atoms::boxWasSet() const {
275 : return boxHasBeenSet;
276 : }
277 :
278 : inline
279 : const Tensor& Atoms::getVirial()const {
280 450 : return virial;
281 : }
282 :
283 :
284 : }
285 : #endif
|