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_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::vector<Vector> positions;
51 : std::vector<Vector> forces;
52 : std::vector<double> masses;
53 : std::vector<double> charges;
54 : std::vector<ActionWithVirtualAtom*> virtualAtomsActions;
55 : Tensor box;
56 : Pbc& pbc;
57 : Tensor virial;
58 : // this is the energy set by each processor:
59 : double md_energy;
60 : // this is the summed energy:
61 : double energy;
62 :
63 : bool dataCanBeSet;
64 : bool collectEnergy;
65 : bool energyHasBeenSet;
66 : unsigned positionsHaveBeenSet;
67 : bool massesHaveBeenSet;
68 : bool chargesHaveBeenSet;
69 : bool boxHasBeenSet;
70 : unsigned forcesHaveBeenSet;
71 : bool virialHasBeenSet;
72 : bool massAndChargeOK;
73 : unsigned shuffledAtoms;
74 :
75 : std::map<std::string,std::vector<AtomNumber> > groups;
76 :
77 : void resizeVectors(unsigned);
78 :
79 : std::vector<int> fullList;
80 :
81 : MDAtomsBase* mdatoms;
82 :
83 : PlumedMain & plumed;
84 :
85 : Units MDUnits;
86 : Units units;
87 :
88 : bool naturalUnits;
89 : bool MDnaturalUnits;
90 :
91 : double timestep;
92 : double forceOnEnergy;
93 :
94 : /// if set to true, all the forces in the global array are zeroes
95 : /// at every step. It should not be necessary in general, but it is
96 : /// for actions accessing to modifyGlobalForce() (e.g. FIT_TO_TEMPLATE).
97 : bool zeroallforces;
98 :
99 : double kbT;
100 :
101 : std::vector<const ActionAtomistic*> actions;
102 : std::vector<int> gatindex;
103 :
104 : bool asyncSent;
105 : bool atomsNeeded;
106 :
107 1159 : class DomainDecomposition:
108 : public Communicator
109 : {
110 : public:
111 : bool on;
112 : bool async;
113 : std::vector<int> g2l;
114 :
115 : std::vector<Communicator::Request> mpi_request_positions;
116 : std::vector<Communicator::Request> mpi_request_index;
117 :
118 : std::vector<double> positionsToBeSent;
119 : std::vector<double> positionsToBeReceived;
120 : std::vector<int> indexToBeSent;
121 : std::vector<int> indexToBeReceived;
122 113710 : operator bool() const {return on;}
123 1159 : DomainDecomposition():
124 1159 : on(false), async(false)
125 1159 : {}
126 : void enable(Communicator& c);
127 : };
128 :
129 : DomainDecomposition dd;
130 : long int ddStep; //last step in which dd happened
131 :
132 : void share(const std::set<AtomNumber>&);
133 :
134 : public:
135 :
136 : explicit Atoms(PlumedMain&plumed);
137 : ~Atoms();
138 :
139 : void init();
140 :
141 : void share();
142 : void shareAll();
143 : void wait();
144 : void updateForces();
145 :
146 : void setRealPrecision(int);
147 : int getRealPrecision()const;
148 :
149 : void setTimeStep(void*);
150 : double getTimeStep()const;
151 :
152 : void setKbT(void*);
153 : double getKbT()const;
154 :
155 : void setNatoms(int);
156 : const int & getNatoms()const;
157 :
158 : const long int& getDdStep()const;
159 : const std::vector<int>& getGatindex()const;
160 : const Pbc& getPbc()const;
161 : void getLocalMasses(std::vector<double>&);
162 : void getLocalPositions(std::vector<Vector>&);
163 : void getLocalForces(std::vector<Vector>&);
164 : void getLocalMDForces(std::vector<Vector>&);
165 : const Tensor& getVirial()const;
166 :
167 250 : void setCollectEnergy(bool b) { collectEnergy=b; }
168 :
169 : void setDomainDecomposition(Communicator&);
170 : void setAtomsGatindex(int*,bool);
171 : void setAtomsContiguous(int);
172 : void setAtomsNlocal(int);
173 :
174 : void startStep();
175 : void setEnergy(void*);
176 : void setBox(void*);
177 : void setVirial(void*);
178 : void setPositions(void*);
179 : void setPositions(void*,int);
180 : void setForces(void*);
181 : void setForces(void*,int);
182 : void setMasses(void*);
183 : void setCharges(void*);
184 : bool chargesWereSet() const ;
185 : bool boxWasSet() const ;
186 :
187 : void MD2double(const void*m,double&d)const;
188 : void double2MD(const double&d,void*m)const;
189 :
190 : void createFullList(int*);
191 : void getFullList(int**);
192 : void clearFullList();
193 :
194 : void add(const ActionAtomistic*);
195 : void remove(const ActionAtomistic*);
196 :
197 250 : double getEnergy()const {plumed_assert(collectEnergy && energyHasBeenSet); return energy;}
198 :
199 0 : bool isEnergyNeeded()const {return collectEnergy;}
200 :
201 0 : void setMDEnergyUnits(double d) {MDUnits.setEnergy(d);}
202 288 : void setMDLengthUnits(double d) {MDUnits.setLength(d);}
203 0 : void setMDTimeUnits(double d) {MDUnits.setTime(d);}
204 288 : void setMDChargeUnits(double d) {MDUnits.setCharge(d);}
205 288 : void setMDMassUnits(double d) {MDUnits.setMass(d);}
206 191 : const Units& getMDUnits() {return MDUnits;}
207 12 : void setUnits(const Units&u) {units=u;}
208 2358 : const Units& getUnits() {return units;}
209 : void updateUnits();
210 :
211 : AtomNumber addVirtualAtom(ActionWithVirtualAtom*);
212 : void removeVirtualAtom(ActionWithVirtualAtom*);
213 : ActionWithVirtualAtom* getVirtualAtomsAction(AtomNumber)const;
214 : bool isVirtualAtom(AtomNumber)const;
215 : void insertGroup(const std::string&name,const std::vector<AtomNumber>&a);
216 : void removeGroup(const std::string&name);
217 : void writeBinary(std::ostream&)const;
218 : void readBinary(std::istream&);
219 : double getKBoltzmann()const;
220 : double getMDKBoltzmann()const;
221 : bool usingNaturalUnits()const;
222 12 : void setNaturalUnits(bool n) {naturalUnits=n;}
223 0 : void setMDNaturalUnits(bool n) {MDnaturalUnits=n;}
224 : };
225 :
226 : inline
227 254227 : const int & Atoms::getNatoms()const {
228 254227 : return natoms;
229 : }
230 :
231 : inline
232 0 : const long int& Atoms::getDdStep()const {
233 0 : return ddStep;
234 : }
235 :
236 : inline
237 0 : const std::vector<int>& Atoms::getGatindex()const {
238 0 : return gatindex;
239 : }
240 :
241 : inline
242 0 : const Pbc& Atoms::getPbc()const {
243 0 : return pbc;
244 : }
245 :
246 : inline
247 172355 : bool Atoms::isVirtualAtom(AtomNumber i)const {
248 172355 : return i.index()>=(unsigned) getNatoms();
249 : }
250 :
251 : inline
252 143 : ActionWithVirtualAtom* Atoms::getVirtualAtomsAction(AtomNumber i)const {
253 143 : return virtualAtomsActions[i.index()-getNatoms()];
254 : }
255 :
256 : inline
257 1506 : bool Atoms::usingNaturalUnits() const {
258 1506 : return naturalUnits || MDnaturalUnits;
259 : }
260 :
261 : inline
262 58944 : bool Atoms::chargesWereSet() const {
263 58944 : return chargesHaveBeenSet;
264 : }
265 :
266 : inline
267 : bool Atoms::boxWasSet() const {
268 : return boxHasBeenSet;
269 : }
270 :
271 : inline
272 0 : const Tensor& Atoms::getVirial()const {
273 0 : return virial;
274 : }
275 :
276 :
277 : }
278 : #endif
|