Simpatico  v1.10
mcMd/neighbor/CellList.h
1 #ifndef MCMD_CELL_LIST_H
2 #define MCMD_CELL_LIST_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 "Cell.h"
12 #include "CellTag.h"
13 #include <mcMd/chemistry/Atom.h>
14 #include <simp/boundary/Boundary.h>
15 #include <util/space/IntVector.h>
16 #include <util/containers/DArray.h>
17 #include <util/containers/FSArray.h>
18 #include <util/global.h>
19 
20 #include <sstream>
21 
22 class CellListTest;
23 
24 namespace McMd
25 {
26 
27  using namespace Util;
28  using namespace Simp;
29 
56  class CellList
57  {
58 
59  public:
60 
61  // Static members
62 
69  static const int MaxNeighbor = 27*Cell::MaxAtomCell;
70 
77 
78  // Public member functions
79 
83  CellList();
84 
90  virtual ~CellList();
91 
100  void setAtomCapacity(int atomCapacity);
101 
108  template <class Archive>
109  void serialize(Archive& ar, const unsigned int version);
110 
128  void setup(const Boundary &boundary, double cutoff);
129 
136  void clear();
137 
144  int cellIndexFromPosition(const Vector &pos) const;
145 
151  void addAtom(Atom &atom);
152 
158  void deleteAtom(Atom &atom);
159 
175  void updateAtomCell(Atom &atom, const Vector &pos);
176 
189  void
190  getNeighbors(const Vector &pos, NeighborArray &neighbors) const;
191 
208  void
209  getCellNeighbors(int ic, NeighborArray &neighbors, int &nInCell) const;
210 
216  int gridDimension(int i) const;
217 
221  int totCells() const;
222 
226  int nAtom() const;
227 
231  int atomCapacity() const;
232 
242  bool isValid(int nAtom=-1) const;
243 
244  private:
245 
247  DArray<Cell> cells_;
248 
250  DArray<CellTag> cellTags_;
251 
261  Vector lengths_;
262 
269  Vector invCellWidths_;
270 
272  IntVector minDel_;
273 
275  IntVector maxDel_;
276 
278  IntVector numCells_;
279 
281  IntVector minCells_;
282 
284  IntVector maxCells_;
285 
287  int YZCells_;
288 
290  int totCells_;
291 
293  int atomCapacity_;
294 
296  const Boundary* boundaryPtr_;
297 
308  void setCellsAxis(int axis, double cutoff);
309 
319  int shiftCellCoordAxis(int i, int x) const;
320 
328  int cellIndexFromCoord(int cx, int cy, int cz) const;
329 
333  void cellCoordFromIndex(int i, int &cx, int &cy, int &cz) const;
334 
338  bool isValidAtomId(int atomId)
339  { return ( (0 <= atomId) && (atomId < cellTags_.capacity()) ); }
340 
341 
342  //friends:
343 
345  friend class ::CellListTest;
346 
347  };
348 
349 
350  // Public inline function definitions:
351 
352  /*
353  * Get total number of cells in this CellList.
354  */
355  inline int CellList::totCells() const
356  { return totCells_; }
357 
358  /*
359  * Return index of the cell that contains the position array pos = {x, y, z}.
360  */
361  inline int CellList::cellIndexFromPosition(const Vector &pos) const
362  {
363  int cx, cy, cz;
364 
365  {
366  Vector posG;
367  boundaryPtr_->transformCartToGen(pos, posG);
368  cx = int(posG[0]*invCellWidths_[0]);
369  cy = int(posG[1]*invCellWidths_[1]);
370  cz = int(posG[2]*invCellWidths_[2]);
371  }
372 
373  assert(cx >= 0);
374  assert(cx < numCells_[0]);
375  assert(cy >= 0);
376  assert(cy < numCells_[1]);
377  assert(cz >= 0);
378  assert(cz < numCells_[2]);
379 
380  return cz + cy*numCells_[2] + cx*YZCells_;
381  }
382 
383  /*
384  * Remove an Atom object from its Cell.
385  */
386  inline void CellList::deleteAtom(Atom &atom)
387  {
388  int atomId = atom.id();
389  assert(isValidAtomId(atomId));
390  CellTag& cellTag = cellTags_[atomId];
391  cells_[cellTag.cellId].deleteAtom(cellTag);
392  }
393 
394  /*
395  * Add a Atom to the appropriate cell, based on its position.
396  */
397  inline void CellList::addAtom(Atom &atom)
398  {
399  Vector position = atom.position();
400  int cellId = cellIndexFromPosition(position);
401  int atomId = atom.id();
402  assert(isValidAtomId(atomId));
403  cells_[cellId].addAtom(cellTags_[atomId], atom, cellId);
404  }
405 
406  /*
407  * Update CellList to reflect new atom position
408  */
409  inline void CellList::updateAtomCell(Atom &atom, const Vector &pos)
410  {
411  int atomId = atom.id();
412  assert(isValidAtomId(atomId));
413  CellTag& cellTag = cellTags_[atomId];
414  int oldCell = cellTag.cellId;
415  int newCell = cellIndexFromPosition(pos);
416  if (oldCell != newCell) {
417  cells_[oldCell].deleteAtom(cellTag);
418  cells_[newCell].addAtom(cellTag, atom, newCell);
419  }
420  }
421 
422  /*
423  * Fill an array with Ids of atoms that are near a specified position.
424  */
425  inline void
426  CellList::getNeighbors(const Vector &pos, NeighborArray &neighbors) const
427  {
428  int nInCell;
429  int ic = cellIndexFromPosition(pos);
430  getCellNeighbors(ic, neighbors, nInCell);
431  }
432 
433  // Private inline member functions
434 
435  /*
436  * Return value of integer cell coordinate x for axis i shifted to the range
437  * minCells_[i] <= x <= maxCells_[i].
438  */
439  inline int CellList::shiftCellCoordAxis(int i, int x) const
440  {
441  if (x > maxCells_[i]) return x - numCells_[i];
442  if (x < minCells_[i]) return x + numCells_[i];
443  return x;
444  }
445 
446  /*
447  * Return integer index of a cell with integer coordinates (cx,cy,cz).
448  */
449  inline int CellList::cellIndexFromCoord(int cx, int cy, int cz) const
450  {
451  return cx*YZCells_ + cy*numCells_[2] + cz ;
452  }
453 
454  /*
455  * Return (by reference) int coordinates (cx,cy,cz) of cell with index i.
456  */
457  inline
458  void CellList::cellCoordFromIndex(int i, int &cx, int &cy, int &cz) const
459  {
460  cx = (int)(i / YZCells_);
461  i = i - cx*YZCells_;
462  cy = (int)(i / numCells_[2]);
463  cz = i - cy*numCells_[2];
464  }
465 
466  inline int CellList::gridDimension(int i) const
467  { return numCells_[i]; }
468 
469  /*
470  * Serialize to/from an Archive.
471  */
472  template <class Archive>
473  void CellList::serialize(Archive& ar, const unsigned int version)
474  {
475  ar & lengths_;
476  ar & invCellWidths_;
477  ar & minDel_;
478  ar & maxDel_;
479  ar & numCells_;
480  ar & minCells_;
481  ar & maxCells_;
482  ar & YZCells_;
483  ar & totCells_;
484  ar & atomCapacity_;
485  if (ar.is_loading()) {
486  cells_.allocate(totCells_);
487  cellTags_.allocate(atomCapacity_);
488  }
489  clear();
490  }
491 
492 }
493 #endif
A Vector is a Cartesian vector.
Definition: Vector.h:75
void getNeighbors(const Vector &pos, NeighborArray &neighbors) const
Fill a NeighborArray with pointers to atoms near a specified position.
An orthorhombic periodic unit cell.
int cellIndexFromPosition(const Vector &pos) const
Return index of the cell that contains the position pos = (x,y,z).
int cellId
Cell index of Cell containing associated Atom.
Definition: CellTag.h:36
File containing preprocessor macros for error handling.
Classes used by all simpatico molecular simulations.
void serialize(Archive &ar, PairSelector &selector, const unsigned int version)
Serialize a PairSelector.
Definition: PairSelector.h:167
void serialize(Archive &ar, const unsigned int version)
Serialize to/from an Archive.
A point particle within a Molecule.
Utility classes for scientific computation.
Definition: accumulators.mod:1
Location of the pointer to a particular Atom in a CellList.
Definition: CellTag.h:27
int id() const
Get global index for this Atom within the Simulation.
int totCells() const
Get total number of cells in this CellList.
void deleteAtom(Atom &atom)
Delete a Atom object from its cell.
A cell list for Atom objects in a periodic system boundary.
void updateAtomCell(Atom &atom, const Vector &pos)
Update CellList to reflect a new atom position.
static const int MaxAtomCell
Maximum number of atoms per cell.
Dynamically allocatable contiguous array template.
Definition: DArray.h:31
Single-processor Monte Carlo (MC) and molecular dynamics (MD).
An IntVector is an integer Cartesian vector.
Definition: IntVector.h:73
int capacity() const
Return allocated size.
Definition: Array.h:153
void allocate(int capacity)
Allocate the underlying C array.
Definition: DArray.h:191
const Vector & position() const
Get the position Vector by const reference.
int gridDimension(int i) const
Number of cells along axis i.
void addAtom(Atom &atom)
Add a Atom to the appropriate cell, based on its position.
FSArray< Atom *, MaxNeighbor > NeighborArray
Static array for holding neighbors in a cell list.
void transformCartToGen(const Vector &Rc, Vector &Rg) const
Transform Cartesian Vector to scaled / generalized coordinates.