Simpatico  v1.10
ddMd/neighbor/PairList.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 "PairList.h"
9 #include "PairIterator.h"
10 #include <ddMd/chemistry/Atom.h>
11 #include <util/space/Vector.h>
12 #include <util/format/Int.h>
13 #include <util/global.h>
14 
15 namespace DdMd
16 {
17 
18  using namespace Util;
19 
20  /*
21  * Default constructor.
22  */
24  : atom1Ptrs_(),
25  atom2Ptrs_(),
26  first_(),
27  cutoff_(0.0),
28  atomCapacity_(0),
29  pairCapacity_(0),
30  maxNAtomLocal_(0),
31  maxNPairLocal_(0),
32  buildCounter_(0),
33  maxNAtom_(0),
34  maxNPair_(0),
35  isAllocated_(false)
36  {}
37 
38  /*
39  * Destructor.
40  */
42  {}
43 
44  /*
45  * Allocate CellList and PairList arrays, initialize to empty state.
46  */
47  void PairList::allocate(int atomCapacity, int pairCapacity , double cutoff)
48  {
49  atomCapacity_ = atomCapacity;
50  pairCapacity_ = pairCapacity;
51  cutoff_ = cutoff;
52 
53  atom1Ptrs_.reserve(atomCapacity_);
54  atom2Ptrs_.reserve(pairCapacity_);
55  first_.reserve(atomCapacity_ + 1);
56 
57  isAllocated_ = true;
58  }
59 
60  /*
61  * Clear the PairList.
62  */
64  {
65  atom1Ptrs_.clear();
66  atom2Ptrs_.clear();
67  first_.clear();
68  }
69 
70  /*
71  * Build the PairList, i.e., populate it with atom pairs.
72  */
73  void PairList::build(CellList& cellList, bool reverseUpdateFlag)
74  {
75  // Precondition
76  assert(isAllocated());
77 
78  Cell::NeighborArray neighbors;
79  double cutoffSq;
80  const Cell* cellPtr;
81  CellAtom* atom1Ptr;
82  CellAtom* atom2Ptr;
83  Mask* maskPtr;
84  Vector dr;
85  int na; // number of atoms in this cell
86  int nn; // number of neighbors for a cell
87  int i, j;
88  bool hasNeighbor;
89 
90  // Set maximum squared-separation for pairs in Pairlist
91  cutoffSq = cutoff_*cutoff_;
92 
93  // Initialize counters for primary atoms and neighbors
94  atom1Ptrs_.clear();
95  atom2Ptrs_.clear();
96  first_.clear();
97  first_.append(0);
98 
99  // Copy positions and ids into cell list
100  cellList.update();
101 
102  // Find all neighbors (cell list)
103  cellPtr = cellList.begin();
104  while (cellPtr) {
105  na = cellPtr->nAtom(); // # of atoms in cell
106 
107  if (na) {
108  cellPtr->getNeighbors(neighbors, reverseUpdateFlag);
109  nn = neighbors.size();
110 
111  // Loop over primary atoms (atom1) in primary cell
112  for (i = 0; i < na; ++i) {
113  atom1Ptr = neighbors[i];
114  maskPtr = atom1Ptr->maskPtr();
115 
116  // Loop over secondary atoms
117  hasNeighbor = false;
118  for (j = i + 1; j < nn; ++j) {
119  atom2Ptr = neighbors[j];
120  dr.subtract(atom2Ptr->position(), atom1Ptr->position());
121  if (dr.square() < cutoffSq && !maskPtr->isMasked(atom2Ptr->id())) {
122  atom2Ptrs_.append(atom2Ptr->ptr());
123  hasNeighbor = true;
124  }
125  }
126 
127  // Complete processing of atom1.
128  if (hasNeighbor) {
129  atom1Ptrs_.append(atom1Ptr->ptr());
130  first_.append(atom2Ptrs_.size());
131  }
132 
133  } // for ia
134  } // if (na)
135 
136  // Advance to next cell in a linked list
137  cellPtr = cellPtr->nextCellPtr();
138  }
139 
140  // Postconditions
141  if (atom1Ptrs_.size()) {
142  if (first_.size() != atom1Ptrs_.size() + 1) {
143  UTIL_THROW("Array size problem");
144  }
145  if (first_[0] != 0) {
146  UTIL_THROW("Incorrect first element of first_");
147  }
148  if (first_[atom1Ptrs_.size()] != atom2Ptrs_.size()) {
149  UTIL_THROW("Incorrect last element of first_");
150  }
151  }
152 
153  // Increment buildCounter_= number of times the list has been built.
154  ++buildCounter_;
155 
156  // Increment maxima
157  if (atom1Ptrs_.size() > maxNAtomLocal_) {
158  maxNAtomLocal_ = atom1Ptrs_.size();
159  }
160  if (atom2Ptrs_.size() > maxNPairLocal_) {
161  maxNPairLocal_ = atom2Ptrs_.size();
162  }
163  }
164 
165  /*
166  * Initialize a pair iterator.
167  */
168  void PairList::begin(PairIterator& iterator) const
169  {
170  if (atom1Ptrs_.size()) {
171  iterator.atom1Ptrs_ = &atom1Ptrs_[0];
172  iterator.atom2Ptrs_ = &atom2Ptrs_[0];
173  iterator.first_ = &first_[0];
174  iterator.nAtom1_ = atom1Ptrs_.size();
175  iterator.nAtom2_ = atom2Ptrs_.size();
176  iterator.atom1Id_ = 0;
177  iterator.atom2Id_ = 0;
178  }
179  }
180 
181  /*
182  * Compute memory usage statistics (call on all processors).
183  */
184  #ifdef UTIL_MPI
185  void PairList::computeStatistics(MPI::Intracomm& communicator)
186  #else
188  #endif
189  {
190  #ifdef UTIL_MPI
191  int maxNAtomGlobal;
192  int maxNPairGlobal;
193  communicator.Allreduce(&maxNAtomLocal_, &maxNAtomGlobal, 1,
194  MPI::INT, MPI::MAX);
195  communicator.Allreduce(&maxNPairLocal_, &maxNPairGlobal, 1,
196  MPI::INT, MPI::MAX);
197  maxNAtom_.set(maxNAtomGlobal);
198  maxNPair_.set(maxNPairGlobal);
199  maxNAtomLocal_ = maxNAtomGlobal;
200  maxNPairLocal_ = maxNPairGlobal;
201  #else
202  maxNAtom_.set(maxNAtomLocal_);
203  maxNPair_.set(maxNPairLocal_);
204  #endif
205  }
206 
207  /*
208  * Clear all statistics.
209  */
211  {
212  maxNAtomLocal_ = 0;
213  maxNPairLocal_ = 0;
214  maxNAtom_.unset();
215  maxNPair_.unset();
216  buildCounter_ = 0;
217  }
218 
219  /*
220  * Output statistics.
221  */
222  void PairList::outputStatistics(std::ostream& out)
223  {
224 
225  out << std::endl;
226  out << "PairList" << std::endl;
227  out << "NPair: max, capacity "
228  << Int(maxNPair_.value(), 10)
229  << Int(pairCapacity_, 10)
230  << std::endl;
231  out << "NAtom: max, capacity "
232  << Int(maxNAtom_.value(), 10)
233  << Int(atomCapacity_, 10)
234  << std::endl;
235  }
236 
237 }
const Cell * begin() const
Return pointer to first local cell in linked list.
Set of Atoms for which pair interactions with a parent Atom are "masked".
A cell list used only to identify nearby atom pairs.
int atomCapacity() const
Get the maximum number of primary atoms.
A Vector is a Cartesian vector.
Definition: Vector.h:75
Data for an atom in a CellList.
void append(const Data &data)
Append an element to the end of the sequence.
Definition: GArray.h:306
void clear()
Reset to empty state.
Definition: GArray.h:299
void clearStatistics()
Clear statistical accumulators (call on all processors).
void set(const T &value)
Set the value and mark as set.
Definition: Setable.h:107
void outputStatistics(std::ostream &out)
Output statistics.
void reserve(int capacity)
Reserve memory for specified number of elements.
Definition: GArray.h:255
virtual ~PairList()
Destructor.
int size() const
Return logical size of this array (i.e., current number of elements).
Definition: GArray.h:455
File containing preprocessor macros for error handling.
PairList()
Default constructor.
void begin(PairIterator &iterator) const
Initialize a PairIterator.
Parallel domain decomposition (DD) MD simulation.
bool isMasked(int id) const
True if the atom is in the masked set for the parent Atom.
void clear()
Reset this to empty state.
A fixed capacity (static) contiguous array with a variable logical size.
Definition: FSArray.h:37
const T & value() const
Return value (if set).
Definition: Setable.h:132
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition: global.h:51
virtual void computeStatistics(MPI::Intracomm &communicator)
Compute statistics (reduce from all processors).
void update()
Update the cell list.
int nAtom() const
Number of atoms in cell.
Utility classes for scientific computation.
Definition: accumulators.mod:1
Wrapper for an int, for formatted ostream output.
Definition: Int.h:36
void build(CellList &cellList, bool reverseUpdateFlag=false)
Use a CellList to build a new PairList.
void unset()
Unset the value (mark as unknown).
Definition: Setable.h:116
void allocate(int atomCapacity, int pairCapacity, double cutoff)
Allocate memory and set cutoff.
void getNeighbors(NeighborArray &neighbors, bool reverseUpdateFlag=false) const
Fill an array with pointers to atoms in a cell and neighboring cells.
Vector & subtract(const Vector &v1, const Vector &v2)
Subtract vector v2 from v1.
Definition: Vector.h:672
Iterator for pairs in a PairList.
bool isAllocated() const
Has memory been allocated for this PairList?
int size() const
Return logical size of this array (i.e., number of elements).
Definition: FSArray.h:207
double square() const
Return square magnitude of this vector.
Definition: Vector.h:616
const Cell * nextCellPtr() const
Return a pointer to neighbor cell i.
int pairCapacity() const
Get the maximum number of pairs.
A single Cell in a CellList.