Simpatico  v1.10
AtomMap.cpp
1 /*
2 * Simpatico - Simulation Package for Polymeric and Molecular Liquids
3 *
4 * Copyright 2010 - 2017, The Regents of the University of Minnesota
5 * Distributed under the terms of the GNU General Public License.
6 */
7 
8 #include "AtomMap.h"
9 #include <ddMd/storage/ConstGhostIterator.h>
10 #include <util/containers/ArraySet.h>
11 #include <util/global.h>
12 
13 #include <utility>
14 
15 namespace DdMd
16 {
17 
18  using namespace Util;
19 
20  /*
21  * Default constructor.
22  */
24  : atomPtrs_(),
25  nLocal_(0),
26  nGhostDistinct_(0),
27  totalAtomCapacity_(0),
28  isInitialized_(false)
29  {}
30 
31  /*
32  * Destructor.
33  */
35  {}
36 
37  /*
38  * Allocate and initialize all containers (private).
39  */
40  void AtomMap::allocate(int totalAtomCapacity)
41  {
42  // Precondition
43  if (isInitialized_) {
44  UTIL_THROW("AtomMap can only be initialized once");
45  }
46  atomPtrs_.allocate(totalAtomCapacity);
47  totalAtomCapacity_ = totalAtomCapacity;
48  for (int i = 0; i < totalAtomCapacity_; ++i) {
49  atomPtrs_[i] = 0;
50  }
51  isInitialized_ = true;
52  }
53 
54  /*
55  * Register new local Atom in internal data structures.
56  */
58  {
59 
60  // Preconditions
61  int atomId = ptr->id();
62  if (atomId < 0 || atomId >= totalAtomCapacity_) {
63  Log::file() << "atomId = " << atomId << std::endl;
64  UTIL_THROW("atomId is out of range");
65  }
66  if (atomPtrs_[atomId]) {
67  Log::file() << "atomId = " << atomId << std::endl;
68  Log::file() << "New Position = " << ptr->position()
69  << std::endl;
70  Log::file() << "Old Position = " << atomPtrs_[atomId]->position()
71  << std::endl;
72  UTIL_THROW("Local atom with specified id is already present");
73  }
74 
75  // Add
76  atomPtrs_[atomId] = ptr;
77  ++nLocal_;
78  }
79 
80  /*
81  * Remove a specific local Atom.
82  */
84  {
85  int atomId = ptr->id();
86  if (atomId < 0 || atomId >= totalAtomCapacity_) {
87  Log::file() << "atomId = " << atomId << std::endl;
88  UTIL_THROW("atomId is out of range");
89  }
90  if (ptr == atomPtrs_[atomId]) {
91 
92  // Remove from atomPtrs_
93  atomPtrs_[atomId] = 0;
94  --nLocal_;
95 
96  // If possible, move an atom from ghostMap to atomPtrs_
97  if (!ghostMap_.empty()) {
98  GhostMap::iterator iter = ghostMap_.find(atomId);
99  if (iter != ghostMap_.end()) {
100  atomPtrs_[atomId] = iter->second;
101  ++nGhostDistinct_;
102  ghostMap_.erase(iter);
103  }
104  }
105 
106  } else {
107  if (0 == atomPtrs_[atomId]) {
108  UTIL_THROW("Error: Attempt to remove absent local atom");
109  } else {
110  UTIL_THROW("Error: Inconsistent pointer");
111  }
112  }
113  }
114 
115  // Ghost atom mutators
116 
117  /*
118  * Register new ghost Atom to internal data structures.
119  */
121  {
122  int atomId = ptr->id();
123  if (atomId < 0 || atomId >= totalAtomCapacity_) {
124  UTIL_THROW("atomId is out of range");
125  }
126 
127  if (0 == atomPtrs_[atomId]) {
128  atomPtrs_[atomId] = ptr;
129  ++nGhostDistinct_;
130  } else {
131  ghostMap_.insert(std::pair<int, Atom*>(atomId, ptr));
132  //ghostMap_.emplace(atomId, ptr);
133  }
134  }
135 
136  /*
137  * Remove a specific ghost Atom.
138  */
140  {
141  int atomId = ptr->id();
142  if (atomId < 0 || atomId >= totalAtomCapacity_) {
143  UTIL_THROW("atomId is out of range");
144  }
145 
146  if (atomPtrs_[atomId] == ptr) {
147 
148  // Remove from atomPtrs array
149  atomPtrs_[atomId] = 0;
150  --nGhostDistinct_;
151 
152  // If possible, move an atom from ghostMap to atomPtrs_
153  if (!ghostMap_.empty()) {
154  GhostMap::iterator iter = ghostMap_.find(atomId);
155  if (iter != ghostMap_.end()) {
156  atomPtrs_[atomId] = iter->second;
157  ++nGhostDistinct_;
158  ghostMap_.erase(iter);
159  }
160  }
161 
162  } else { // If ptr is not found in atomPtrs
163 
164  if (atomPtrs_[atomId] != 0) {
165  // Search ghost map
166  std::pair<GhostMap::iterator, GhostMap::iterator> ret;
167  ret = ghostMap_.equal_range(atomId);
168  GhostMap::iterator it = ret.first;
169  GhostMap::iterator last = ret.second;
170  for ( ; it != last; ++it) {
171  assert(it->first == atomId);
172  if (it->second == ptr) {
173  ghostMap_.erase(it);
174  return;
175  }
176  }
177  UTIL_THROW("Error: Attempt to remove absent ghost");
178  } else {
179  UTIL_THROW("Error: Attempt to remove absent ghost");
180  }
181  }
182 
183  }
184 
185  void AtomMap::clearGhosts(const ArraySet<Atom>& ghostSet)
186  {
187  // Precondition
188  if (ghostSet.size() != nGhost()) {
189  UTIL_THROW("Inconsistent ghost set sizes");
190  }
191 
192  // Clear extra ghost images from ghostMap_
193  ghostMap_.clear();
194 
195  // Clear ghosts from atomPtrs_ array
196  ConstGhostIterator iter;
197  const Atom* ptr;
198  int id;
199  for (ghostSet.begin(iter); iter.notEnd(); ++iter) {
200  id = iter->id();
201  ptr = iter.get();
202  if (atomPtrs_[id] == ptr) {
203  atomPtrs_[id] = 0;
204  --nGhostDistinct_;
205  }
206  }
207 
208  }
209 
210  /*
211  * Check validity of this AtomMap.
212  *
213  * Returns true if all is ok, or throws an Exception.
214  */
215  bool AtomMap::isValid() const
216  {
217  Atom* ptr;
218  int i, id, nAtom;
219 
220  // Validate atomPtrs_
221  nAtom = 0;
222  for (i = 0; i < totalAtomCapacity_ ; ++i) {
223  ptr = atomPtrs_[i];
224  if (ptr != 0) {
225  id = ptr->id();
226  if (id != i) {
227  Log::file() << std::endl;
228  Log::file() << "Index i in atomPtrs_ " << i << std::endl;
229  Log::file() << "atomPtrs_[i]->id() " << id << std::endl;
230  UTIL_THROW("ptr->id() != i");
231  }
232  ++nAtom;
233  }
234  }
235  if (nAtom != nLocal_ + nGhostDistinct_) {
236  UTIL_THROW("Inconsistent count of atoms in atomPtrs");
237  }
238 
239  // Validate ghostMap_
240  GhostMap::const_iterator it;
241  for (it = ghostMap_.begin(); it != ghostMap_.end(); ++it) {
242  id = it->first;
243  ptr = it->second;
244  if (id != ptr->id()) {
245  Log::file() << std::endl;
246  Log::file() << "key ghostMap " << id << std::endl;
247  Log::file() << "Atom::id() " << ptr->id() << std::endl;
248  UTIL_THROW("Inconsistent key in ghostMap");
249  }
250  if (atomPtrs_[id] == 0) {
251  UTIL_THROW("Id in ghostMap_ does not appear in atomPtrs_");
252  }
253  }
254  return true;
255  }
256 
257 }
void begin(PArrayIterator< Data > &iterator) const
Set a PArrayIterator to the beginning of this PArray.
Definition: PArray.h:146
const Data * get() const
Return a pointer to const current data.
bool isValid() const
Check validity of this AtomMap.
Definition: AtomMap.cpp:215
void addLocal(Atom *ptr)
Add local atom.
Definition: AtomMap.cpp:57
Vector & position()
Get position Vector by reference.
void allocate(int totalAtomCapacity)
Set parameters, allocate memory and initialize.
Definition: AtomMap.cpp:40
File containing preprocessor macros for error handling.
A point particle in an MD simulation.
Parallel domain decomposition (DD) MD simulation.
int id() const
Get unique global index for this atom.
void removeLocal(Atom *ptr)
Remove a specific Atom.
Definition: AtomMap.cpp:83
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition: global.h:51
A container for pointers to a subset of elements of an associated array.
Definition: ArraySet.h:46
int nGhost() const
Return the number of ghosts, including images.
Definition: AtomMap.h:248
Utility classes for scientific computation.
Definition: accumulators.mod:1
static std::ostream & file()
Get log ostream by reference.
Definition: Log.cpp:57
bool notEnd() const
Is the current pointer not at the end of the array?
~AtomMap()
Destructor.
Definition: AtomMap.cpp:34
int size() const
Return logical size.
Definition: PArray.h:137
Iterator for all ghost atoms owned by an AtomStorage.
void removeGhost(Atom *ptr)
Remove a ghost Atom.
Definition: AtomMap.cpp:139
void addGhost(Atom *ptr)
Add ghost atom.
Definition: AtomMap.cpp:120
AtomMap()
Constructor.
Definition: AtomMap.cpp:23
void clearGhosts(const ArraySet< Atom > &ghostSet)
Clear all ghosts from this map.
Definition: AtomMap.cpp:185