8 #include "AtomStorage.h" 9 #include "AtomIterator.h" 10 #include "ConstAtomIterator.h" 11 #include "GhostIterator.h" 12 #include "ConstGhostIterator.h" 13 #include <ddMd/chemistry/Group.h> 14 #include <util/format/Int.h> 15 #include <util/mpi/MpiLoader.h> 38 totalAtomCapacity_(0),
47 isInitialized_(false),
63 distributor_.
associate(domain, boundary, *
this, buffer);
64 collector_.
associate(domain, *
this, buffer);
84 read<int>(in,
"atomCapacity", atomCapacity_);
85 read<int>(in,
"ghostCapacity", ghostCapacity_);
86 read<int>(in,
"totalAtomCapacity", totalAtomCapacity_);
95 loadParameter<int>(ar,
"atomCapacity", atomCapacity_);
96 loadParameter<int>(ar,
"ghostCapacity", ghostCapacity_);
97 loadParameter<int>(ar,
"totalAtomCapacity", totalAtomCapacity_);
99 loader.load(maxNAtomLocal_);
100 loader.load(maxNGhostLocal_);
110 ar << ghostCapacity_;
111 ar << totalAtomCapacity_;
112 ar << maxNAtomLocal_;
113 ar << maxNGhostLocal_;
119 void AtomStorage::allocate()
122 if (isInitialized_) {
123 UTIL_THROW(
"AtomStorage can only be initialized once");
127 atomReservoir_.allocate(atomCapacity_);
128 atomSet_.allocate(atoms_);
130 for (i = atomCapacity_ - 1; i >=0; --i) {
131 atomReservoir_.push(atoms_[i]);
135 ghostReservoir_.allocate(ghostCapacity_);
136 ghostSet_.allocate(ghosts_);
137 for (i = ghostCapacity_ - 1; i >=0; --i) {
138 ghostReservoir_.push(ghosts_[i]);
142 snapshot_.allocate(atomCapacity_);
144 isInitialized_ =
true;
155 if (
nAtom() > atomCapacity_/factor) {
161 for( ; atomIter.
notEnd(); ++atomIter){
162 atomIter->force().zero();
167 if (zeroGhosts &&
nGhost()) {
168 if (
nGhost() > ghostCapacity_/factor) {
174 for( ; ghostIter.
notEnd(); ++ghostIter){
175 ghostIter->force().zero();
190 if (newAtomPtr_ != 0) {
191 UTIL_THROW(
"Unregistered newAtomPtr_ still active");
196 if (atomReservoir_.size() == 0) {
197 UTIL_THROW(
"Cannot pop from empty atomReservoir");
200 newAtomPtr_ = &atomReservoir_.pop();
201 newAtomPtr_->
clear();
210 if (newAtomPtr_ == 0)
217 atomSet_.append(*newAtomPtr_);
224 if (atomSet_.size() > maxNAtomLocal_) {
225 maxNAtomLocal_ = atomSet_.size();
243 atomSet_.remove(*atomPtr);
244 atomReservoir_.push(*atomPtr);
258 while (atomSet_.size() > 0) {
259 atomPtr = &atomSet_.pop();
261 atomReservoir_.push(*atomPtr);
265 if (atomSet_.size() != 0) {
266 UTIL_THROW(
"Nonzero atomSet size at end of clearAtoms");
269 UTIL_THROW(
"Nonzero nLocal in atom map at end of clearAtoms");
281 if (newGhostPtr_ != 0)
282 UTIL_THROW(
"Unregistered newGhostPtr_ still active");
285 if (ghostReservoir_.size() == 0)
286 UTIL_THROW(
"Atom to pop from empty atomReservoir");
288 newGhostPtr_ = &ghostReservoir_.pop();
289 newGhostPtr_->
clear();
299 if (newGhostPtr_ == 0) {
308 ghostSet_.append(*newGhostPtr_);
315 if (ghostSet_.size() > maxNGhostLocal_) {
316 maxNGhostLocal_ = ghostSet_.size();
334 if (locked_)
UTIL_THROW(
"AtomStorage is locked");
337 ghostSet_.remove(*atomPtr);
338 ghostReservoir_.push(*atomPtr);
355 while (ghostSet_.size() > 0) {
356 atomPtr = &ghostSet_.pop();
357 ghostReservoir_.push(*atomPtr);
360 if (ghostSet_.size() != 0) {
361 UTIL_THROW(
"Nonzero ghostSet size at end of clearGhosts");
364 UTIL_THROW(
"Nonzero nGhost in map at end of clearGhosts");
367 UTIL_THROW(
"Nonzero nGhostDistinct at end of clearGhosts");
380 UTIL_THROW(
"Error: Coordinates not Cartesian in makeSnapshot");
386 snapshot_[i] = iter->position();
406 UTIL_THROW(
"Error: Coordinates not Cartesian in maxSqDisplacement");
409 UTIL_THROW(
"Error: AtomStorage not locked in maxSqDisplacement");
417 dr.
subtract(iter->position(), snapshot_[i]);
433 { atomSet_.begin(iterator); }
439 { atomSet_.begin(iterator); }
445 { ghostSet_.begin(iterator); }
451 { ghostSet_.begin(iterator); }
459 UTIL_THROW(
"Error: Coordinates not Cartesian on entry");
464 for (
begin(atomIter); atomIter.
notEnd(); ++atomIter) {
465 r = atomIter->position();
471 for (
begin(ghostIter); ghostIter.
notEnd(); ++ghostIter) {
472 r = ghostIter->position();
476 isCartesian_ =
false;
485 UTIL_THROW(
"Error: Coordinates are Cartesian on entry");
490 for (
begin(atomIter); atomIter.
notEnd(); ++atomIter) {
491 r = atomIter->position();
497 for (
begin(ghostIter); ghostIter.
notEnd(); ++ghostIter) {
498 r = ghostIter->position();
514 int nAtomLocal =
nAtom();
516 communicator.Reduce(&nAtomLocal, &nAtomTotal, 1,
517 MPI::INT, MPI::SUM, 0);
518 if (communicator.Get_rank() !=0) {
521 nAtomTotal_.
set(nAtomTotal);
525 { nAtomTotal_.
unset(); }
539 communicator.Allreduce(&maxNAtomLocal_, &maxNAtomGlobal, 1,
541 maxNAtom_.
set(maxNAtomGlobal);
542 maxNAtomLocal_ = maxNAtomGlobal;
544 maxNAtom_.
set(maxNAtomLocal_);
549 communicator.Allreduce(&maxNGhostLocal_, &maxNGhostGlobal, 1,
551 maxNGhost_.
set(maxNGhostGlobal);
552 maxNGhostLocal_ = maxNGhostGlobal;
554 maxNGhost_.
set(maxNGhostLocal_);
576 out <<
"AtomStorage" << std::endl;
577 out <<
"NAtom: max, capacity " 579 <<
Int(atomCapacity_, 10)
581 out <<
"NGhost: max, capacity " 583 <<
Int(ghostCapacity_, 10)
594 if (
nAtom() + atomReservoir_.size() != atomCapacity_) {
595 UTIL_THROW(
"nAtom + reservoir size != local capacity");
597 if (
nGhost() + ghostReservoir_.size() != ghostCapacity_) {
598 UTIL_THROW(
"nGhost + reservoir size != ghost capacity");
611 for (
begin(localIter); localIter.
notEnd(); ++localIter) {
613 if (localIter->isGhost()) {
614 UTIL_THROW(
"Atom in atomSet is marked isGhost");
616 ptr = map_.
find(localIter->id());
618 UTIL_THROW(
"Unable to find local atom returned by iterator");
620 if (ptr != localIter.
get()) {
621 UTIL_THROW(
"Inconsistent find(localIter->id()");
625 UTIL_THROW(
"Number counted by localIterator != nAtom()");
631 for (
begin(ghostIter); ghostIter.
notEnd(); ++ghostIter) {
633 if (!ghostIter->isGhost()) {
634 UTIL_THROW(
"Atom in ghostSet is not marked isGhost");
636 ptr = map_.
find(ghostIter->id());
647 UTIL_THROW(
"Number counted by ghostIterator != nGhost()");
663 nAtomTotal_.
isValid(communicator);
void addNewGhost()
Register the most recent new ghost atom.
void makeSnapshot()
Record current positions of all local atoms and lock storage.
Atom * newAtomPtr()
Returns pointer an address available for a new Atom.
void associate(Domain &domain, AtomStorage &storage, Buffer &buffer)
Initialize pointers to associated objects.
void removeGhost(Atom *atomPtr)
Remove a specific ghost Atom.
A Vector is a Cartesian vector.
void transformGenToCart(const Boundary &boundary)
Transform positions from generalized to Cartesian coordinates.
void clearAtoms()
Clear all local atoms.
void allocate(int capacity)
Allocate memory on the heap.
void clearStatistics()
Clear statistical accumulators (call on all processors).
void clear()
Reset integer members to initial null values.
virtual void loadParameters(Serializable::IArchive &ar)
Load internal state from an archive.
int nAtomTotal() const
Get total number of atoms on all processors.
const Data * get() const
Return a pointer to const current data.
void outputStatistics(std::ostream &out)
Output statistics.
void setId(int Id)
Set unique global id for this Atom.
void set(const T &value)
Set the value and mark as set.
An orthorhombic periodic unit cell.
int nGhostDistinct() const
Return the number of ghosts with distinct ids.
bool isValid() const
Check validity of this AtomMap.
void addLocal(Atom *ptr)
Add local atom.
void allocate(int totalAtomCapacity)
Set parameters, allocate memory and initialize.
File containing preprocessor macros for error handling.
virtual void readParameters(std::istream &in)
Read parameters, allocate memory and initialize.
A point particle in an MD simulation.
Parallel domain decomposition (DD) MD simulation.
void removeLocal(Atom *ptr)
Remove a specific Atom.
Atom * addAtom(int id)
Add atom with specified global id.
void addNewAtom()
Finalize addition of the most recent new atom.
int nAtom() const
Return number of local atoms on this procesor (excluding ghosts)
Saving / output archive for binary ostream.
const T & value() const
Return value (if set).
~AtomStorage()
Destructor.
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
int nLocal() const
Return the number of local atoms.
virtual void computeStatistics(MPI::Intracomm &communicator)
Compute statistics (reduce from all processors).
void associate(Domain &domain, Boundary &boundary, AtomStorage &storage, Buffer &buffer)
Set pointers to associated objects.
bool isValid(MPI::Intracomm &communicator) const
Test consistency of states on different processors.
int nGhost() const
Return current number of ghost atoms on this processor.
Const iterator for all atoms owned by an AtomStorage.
int nGhost() const
Return the number of ghosts, including images.
bool notEnd() const
Is the current pointer not at the end of the PArray?
Utility classes for scientific computation.
void initialize(int atomCapacity, int ghostCapacity, int totalAtomCapacity)
Set parameters, allocate memory and initialize.
Wrapper for an int, for formatted ostream output.
void setIsGhost(bool isGhost)
Mark as ghost or local atom for this processor.
void associate(Domain &domain, Boundary &boundary, Buffer &buffer)
Create associations for distributor and collector.
Atom * find(int atomId) const
Return pointer to Atom with specified id.
void unset()
Unset the value (mark as unknown).
void transformGenToCart(const Vector &Rg, Vector &Rc) const
Transform Vector of generalized coordinates to Cartesian Vector.
void clearSnapshot()
Clear previous snapshot.
Atom * newGhostPtr()
Returns pointer an address available for a new ghost Atom.
int atomCapacity() const
Return capacity for local atoms on this processor (excluding ghosts).
void computeNAtomTotal(MPI::Intracomm &communicator)
Compute the total number of local atoms on all processors.
int totalAtomCapacity() const
Return maximum number of atoms on all processors.
bool isValid() const
Return true if the container is valid, or throw an Exception.
Buffer for interprocessor communication.
Decomposition of the system into domains associated with processors.
bool notEnd() const
Is the current pointer not at the end of the array?
Saving archive for binary istream.
AtomStorage()
Constructor.
Provides methods for MPI-aware loading of data from input archive.
int ghostCapacity() const
Return capacity for ghost atoms on this processor.
bool isCartesian() const
Are atom coordinates Cartesian (true) or generalized (false)?
Iterator for all ghost atoms owned by an AtomStorage.
Atom * addGhost(int id)
Add ghost atom with specified global id.
virtual void save(Serializable::OArchive &ar)
Save internal state to an archive.
Vector & subtract(const Vector &v1, const Vector &v2)
Subtract vector v2 from v1.
void setClassName(const char *className)
Set class name string.
void clearGhosts()
Clear all ghost atoms.
Iterator for all atoms owned by an AtomStorage.
double maxSqDisplacement()
Return max-squared displacement since the last snapshot.
Iterator for all ghost atoms owned by an AtomStorage.
void removeGhost(Atom *ptr)
Remove a ghost Atom.
void zeroForces()
Set force vector to zero for all atoms in this array.
double square() const
Return square magnitude of this vector.
void begin(AtomIterator &iterator)
Set iterator to beginning of the set of atoms.
void removeAtom(Atom *atomPtr)
Remove a specific Atom.
void addGhost(Atom *ptr)
Add ghost atom.
void transformCartToGen(const Boundary &boundary)
Transform positions from Cartesian to generalized coordinates.
void zeroForces(bool zeroGhosts)
Set all forces to zero.
void clearGhosts(const ArraySet< Atom > &ghostSet)
Clear all ghosts from this map.
void unsetNAtomTotal()
Unset value of NAtomTotal (mark as unknown).
void transformCartToGen(const Vector &Rc, Vector &Rg) const
Transform Cartesian Vector to scaled / generalized coordinates.