source: molecuilder/src/linkedcell.cpp@ a87d5e6

Last change on this file since a87d5e6 was a87d5e6, checked in by Saskia Metzler <metzler@…>, 16 years ago

new function LinkedCell::GetNeighbourBounds()

  • LinkedCell::GetNeighbourBounds() needed as atom or vector to seek nearest neighbour for must not necessarily be contained in the LinkedCell grid itself. Hence, we have to use specific bounds for the NN search which this function returns.
  • Property mode set to 100644
File size: 4.9 KB
Line 
1#include "linkedcell.hpp"
2#include "molecules.hpp"
3
4/** Constructor for class LinkedCell.
5 */
6LinkedCell::LinkedCell()
7{
8 LC = NULL;
9 for(int i=0;i<NDIM;i++)
10 N[i] = 0;
11 index = -1;
12 RADIUS = 0.;
13 max.Zero();
14 min.Zero();
15};
16
17/** Puts all atoms in \a *mol into a linked cell list with cell's lengths of \a RADIUS
18 * \param *mol molecule structure with all Atom's
19 * \param RADIUS edge length of cells
20 */
21LinkedCell::LinkedCell(molecule *mol, double radius)
22{
23 atom *Walker = NULL;
24
25 RADIUS = radius;
26 LC = NULL;
27 for(int i=0;i<NDIM;i++)
28 N[i] = 0;
29 index = -1;
30 max.Zero();
31 min.Zero();
32 cout << Verbose(1) << "Begin of LinkedCell" << endl;
33 if (mol->start->next == mol->end) {
34 cerr << "ERROR: molecule contains no atoms!" << endl;
35 return;
36 }
37 // 1. find max and min per axis of atoms
38 Walker = mol->start->next;
39 for (int i=0;i<NDIM;i++) {
40 max.x[i] = Walker->x.x[i];
41 min.x[i] = Walker->x.x[i];
42 }
43 while (Walker != mol->end) {
44 for (int i=0;i<NDIM;i++) {
45 if (max.x[i] < Walker->x.x[i])
46 max.x[i] = Walker->x.x[i];
47 if (min.x[i] > Walker->x.x[i])
48 min.x[i] = Walker->x.x[i];
49 }
50 Walker = Walker->next;
51 }
52 cout << Verbose(2) << "Bounding box is " << min << " and " << max << "." << endl;
53
54 // 2. find then umber of cells per axis
55 for (int i=0;i<NDIM;i++) {
56 N[i] = (int)floor((max.x[i] - min.x[i])/RADIUS)+1;
57 }
58 cout << Verbose(2) << "Number of cells per axis are " << N[0] << ", " << N[1] << " and " << N[2] << "." << endl;
59
60 // 3. allocate the lists
61 cout << Verbose(2) << "Allocating cells ... ";
62 if (LC != NULL) {
63 cout << Verbose(1) << "ERROR: Linked Cell list is already allocated, I do nothing." << endl;
64 return;
65 }
66 LC = new LinkedAtoms[N[0]*N[1]*N[2]];
67 for (index=0;index<N[0]*N[1]*N[2];index++) {
68 LC [index].clear();
69 }
70 cout << "done." << endl;
71
72 // 4. put each atom into its respective cell
73 cout << Verbose(2) << "Filling cells ... ";
74 Walker = mol->start;
75 while (Walker->next != mol->end) {
76 Walker = Walker->next;
77 for (int i=0;i<NDIM;i++) {
78 n[i] = (int)floor((Walker->x.x[i] - min.x[i])/RADIUS);
79 }
80 index = n[0] * N[1] * N[2] + n[1] * N[2] + n[2];
81 LC[index].push_back(Walker);
82 //cout << Verbose(2) << *Walker << " goes into cell " << n[0] << ", " << n[1] << ", " << n[2] << " with No. " << index << "." << endl;
83 }
84 cout << "done." << endl;
85 cout << Verbose(1) << "End of LinkedCell" << endl;
86};
87
88/** Destructor for class LinkedCell.
89 */
90LinkedCell::~LinkedCell()
91{
92 if (LC != NULL)
93 for (index=0;index<N[0]*N[1]*N[2];index++)
94 LC[index].clear();
95 delete[](LC);
96 for(int i=0;i<NDIM;i++)
97 N[i] = 0;
98 index = -1;
99 max.Zero();
100 min.Zero();
101};
102
103/** Checks whether LinkedCell::n[] is each within [0,N[]].
104 * \return if all in intervals - true, else -false
105 */
106bool LinkedCell::CheckBounds()
107{
108 bool status = true;
109 for(int i=0;i<NDIM;i++)
110 status = status && ((n[i] >=0) && (n[i] < N[i]));
111 if (!status)
112 cerr << "ERROR: indices are out of bounds!" << endl;
113 return status;
114};
115
116
117/** Returns a pointer to the current cell.
118 * \return LinkedAtoms pointer to current cell, NULL if LinkedCell::n[] are out of bounds.
119 */
120LinkedAtoms* LinkedCell::GetCurrentCell()
121{
122 if (CheckBounds()) {
123 index = n[0] * N[1] * N[2] + n[1] * N[2] + n[2];
124 return (&(LC[index]));
125 } else {
126 return NULL;
127 }
128};
129
130/** Calculates the index for a given atom *Walker.
131 * \param Walker atom to set index to
132 * \return if the atom is also found in this cell - true, else - false
133 */
134bool LinkedCell::SetIndexToAtom(const atom &Walker)
135{
136 bool status = false;
137 for (int i=0;i<NDIM;i++) {
138 n[i] = (int)floor((Walker.x.x[i] - min.x[i])/RADIUS);
139 }
140
141 index = n[0] * N[1] * N[2] + n[1] * N[2] + n[2];
142 if (CheckBounds()) {
143 for (LinkedAtoms::iterator Runner = LC[index].begin(); Runner != LC[index].end(); Runner++)
144 status = status || ((*Runner) == &Walker);
145 return status;
146 } else {
147 cerr << Verbose(1) << "WARN: Atom "<< Walker << " at " << Walker.x << " is out of bounds." << endl;
148 return false;
149 }
150};
151
152/** Calculates the interval bounds of the linked cell grid.
153 * \param *lower lower bounds
154 * \param *upper upper bounds
155 */
156void LinkedCell::GetNeighbourBounds(int lower[NDIM], int upper[NDIM])
157{
158 for (int i=0;i<NDIM;i++) {
159 lower[i] = ((n[i]-1) >= 0) ? n[i]-1 : 0;
160 upper[i] = ((n[i]+1) < N[i]) ? n[i]+1 : N[i]-1;
161 //cout << " [" << Nlower[i] << "," << Nupper[i] << "] ";
162 // check for this axis whether the point is outside of our grid
163 if (n[i] < 0)
164 upper[i] = lower[i];
165 if (n[i] > N[i])
166 lower[i] = upper[i];
167
168 //cout << "axis " << i << " has bounds [" << lower[i] << "," << upper[i] << "]" << endl;
169 }
170};
171
172/** Calculates the index for a given Vector *x.
173 * \param *x Vector with coordinates
174 * \return Vector is inside bounding box - true, else - false
175 */
176bool LinkedCell::SetIndexToVector(const Vector *x)
177{
178 bool status = true;
179 for (int i=0;i<NDIM;i++) {
180 n[i] = (int)floor((x->x[i] - min.x[i])/RADIUS);
181 if (max.x[i] < x->x[i])
182 status = false;
183 if (min.x[i] > x->x[i])
184 status = false;
185 }
186 return status;
187};
188
Note: See TracBrowser for help on using the repository browser.