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