Simpatico  v1.10
mcMd/neighbor/Cell.h
1 #ifndef MCMD_CELL_H
2 #define MCMD_CELL_H
3 
4 /*
5 * Simpatico - Simulation Package for Polymeric and Molecular Liquids
6 *
7 * Copyright 2010 - 2017, The Regents of the University of Minnesota
8 * Distributed under the terms of the GNU General Public License.
9 */
10 
11 #include "CellTag.h"
12 #include <util/containers/Array.h>
13 #include <util/global.h>
14 
15 class CellTest;
16 class CellListTest;
17 
18 namespace McMd
19 {
20 
21  using namespace Util;
22 
23  class Atom;
24 
40  class Cell
41  {
42 
43  public:
44 
46  #ifdef SIMP_COULOMB
47  static const int MaxAtomCell = 253;
48  #else
49  static const int MaxAtomCell = 61;
50  #endif
51 
53  static const int NullIndex = -1;
54 
58  Cell();
59 
63  void clear();
64 
70  void deleteAtom(CellTag &cellTag);
71 
81  void addAtom(CellTag &cellTag, Atom &atom, int cellId);
82 
84  int nAtomCell() const;
85 
87  int firstClearPos() const;
88 
94  Atom* atomPtr(int index) const;
95 
110  bool isValid(const Array<CellTag> &cellTags, int nAtom, int icell) const;
111 
112  private:
113 
114  /*
115  * Implementation notes:
116  *
117  * Pointers to atoms in a cell are stored in the atoms_[] array member.
118  * "Empty" elements of atoms_[] must contain a null (i.e., 0) pointer.
119  *
120  * The total number of atoms in the cell in is nAtomCell_. The array
121  * index of the first empty element in the atoms_[] array is given by
122  * firstEmptyPos_. All elements of atoms_[] with indices greater than
123  * or equal to firstClearPos_ are empty. An element atoms_[i] with
124  * i < firstEmptyPos_ may not be empty, one with i >= firstClearPos_ must
125  * be empty, and one with firstEmptyPos_ < i < firstClearPos_ may or may
126  * not be empty. When firstClearPos_ > 0, atoms_[firstClearPos_-1] may
127  * not be empty, since this would imply that firstClearPos_ is not the
128  * first in the contiguous block of empty elements. These conditions are
129  * checked in the isValid() method.
130  */
131 
133  Atom* atoms_[MaxAtomCell];
134 
136  int nAtomCell_;
137 
139  int firstEmptyPos_;
140 
142  int firstClearPos_;
143 
144  //friends:
145 
146  // Grant access to unit test classes
147  friend class ::CellTest;
148  friend class ::CellListTest;
149 
150  };
151 
152  // Inline functions
153 
154  /*
155  * Delete atom from Cell
156  */
157  inline void Cell::deleteAtom(CellTag &cellTag)
158  {
159  int cellPos = cellTag.cellPos;
160 
161  // Delete atom from Cell member variables.
162  // Set atoms_[cellPos] to 0 to mark empty.
163  atoms_[cellPos] = 0;
164  nAtomCell_--;
165 
166  // Reset firstEmptyPos_
167  if (firstEmptyPos_ > cellPos) {
168  firstEmptyPos_ = cellPos;
169  }
170 
171  // Reset firstClearPos_
172  int i = firstClearPos_ - 1;
173  while (i >= 0 && atoms_[i] == 0) {
174  i--;
175  }
176  firstClearPos_ = i + 1;
177 
178  // Reset cellTag cellId and cellPos to negative integer values
179  // to indicate that the atom is no longer associated with a Cell.
180  cellTag.cellId = NullIndex;
181  cellTag.cellPos = NullIndex;
182 
183  }
184 
185  /*
186  * Add a atom to a Cell
187  */
188  inline void Cell::addAtom(CellTag &cellTag, Atom &atom, int cellId)
189  {
190 
191  // If cell is already full, throw Exception
192  if (firstEmptyPos_ == MaxAtomCell) {
193  UTIL_THROW("Too many atoms in one cell");
194  }
195 
196  // Add atom to Cell
197  atoms_[firstEmptyPos_] = &atom;
198  ++nAtomCell_;
199 
200  // Record cell in cellTag
201  cellTag.cellId = cellId;
202  cellTag.cellPos = firstEmptyPos_;
203 
204  // Reset firstEmptyPos_ and firstClearPos_
205  if (firstEmptyPos_ < MaxAtomCell - 1) {
206 
207  if (firstEmptyPos_ == firstClearPos_) {
208 
209  firstEmptyPos_ = firstEmptyPos_ + 1;
210  firstClearPos_ = firstClearPos_ + 1;
211 
212  } else {
213 
214  // Find the next empty element, for which atoms_[i] is null
215  for (int i = firstEmptyPos_ + 1; i < MaxAtomCell; ++i) {
216  if (atoms_[i] == 0) {
217  firstEmptyPos_ = i;
218  break;
219  }
220  }
221 
222  }
223 
224  } else {
225 
226  // If firstEmptyPos_ was MaxAtomCell - 1, no empty slots remain.
227  // Set firstEmptyPos_ = MaxAtomCell to indicate this condition.
228  // Attempting to add one more atom will trigger an Exception.
229  firstEmptyPos_ = MaxAtomCell; // Note: Invalid array index
230  firstClearPos_ = MaxAtomCell; // Note: Invalid array index
231 
232  }
233  }
234 
235  inline int Cell::nAtomCell() const
236  { return nAtomCell_; }
237 
238  inline int Cell::firstClearPos() const
239  { return firstClearPos_; }
240 
241  inline Atom* Cell::atomPtr(int index) const
242  { return atoms_[index]; }
243 
244 }
245 
246 #endif
Array container class template.
Definition: AutoCorrArray.h:28
int cellId
Cell index of Cell containing associated Atom.
Definition: CellTag.h:36
File containing preprocessor macros for error handling.
int nAtomCell() const
Get number of atoms in cell.
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition: global.h:51
int cellPos
Array index of Atom pointer in a Cell::part_ array.
Definition: CellTag.h:39
A point particle within a Molecule.
Utility classes for scientific computation.
Definition: accumulators.mod:1
void addAtom(CellTag &cellTag, Atom &atom, int cellId)
Add one atom to a Cell.
Location of the pointer to a particular Atom in a CellList.
Definition: CellTag.h:27
Atom * atomPtr(int index) const
Get a pointer to Atom (may be null).
A set of Atoms in a small region.
int firstClearPos() const
Get index of first clear element of atoms_.
Single-processor Monte Carlo (MC) and molecular dynamics (MD).
void deleteAtom(CellTag &cellTag)
Remove a specified atom from the Cell.