source: molecuilder/src/linkedcell.cpp@ 6f1551

Last change on this file since 6f1551 was 6f1551, checked in by Frederik Heber <heber@…>, 16 years ago

LinkedCell has another constructor initialised from LinkedNodes (list of Nodes).

  • Property mode set to 100644
File size: 7.7 KB
Line 
1/** \file linkedcell.cpp
2 *
3 * Function implementations for the class LinkedCell.
4 *
5 */
6
7
8#include "linkedcell.hpp"
9#include "molecules.hpp"
10#include "tesselation.hpp"
11
12// ========================================================= class LinkedCell ===========================================
13
14
15/** Constructor for class LinkedCell.
16 */
17LinkedCell::LinkedCell()
18{
19 LC = NULL;
20 for(int i=0;i<NDIM;i++)
21 N[i] = 0;
22 index = -1;
23 RADIUS = 0.;
24 max.Zero();
25 min.Zero();
26};
27
28/** Puts all atoms in \a *mol into a linked cell list with cell's lengths of \a RADIUS
29 * \param *set LCNodeSet class with all LCNode's
30 * \param RADIUS edge length of cells
31 */
32LinkedCell::LinkedCell(PointCloud *set, double radius)
33{
34 TesselPoint *Walker = NULL;
35
36 RADIUS = radius;
37 LC = NULL;
38 for(int i=0;i<NDIM;i++)
39 N[i] = 0;
40 index = -1;
41 max.Zero();
42 min.Zero();
43 cout << Verbose(1) << "Begin of LinkedCell" << endl;
44 if (set->IsEmpty()) {
45 cerr << "ERROR: set contains no linked cell nodes!" << endl;
46 return;
47 }
48 // 1. find max and min per axis of atoms
49 set->GoToFirst();
50 Walker = set->GetPoint();
51 for (int i=0;i<NDIM;i++) {
52 max.x[i] = Walker->node->x[i];
53 min.x[i] = Walker->node->x[i];
54 }
55 set->GoToFirst();
56 while (!set->IsEnd()) {
57 Walker = set->GetPoint();
58 for (int i=0;i<NDIM;i++) {
59 if (max.x[i] < Walker->node->x[i])
60 max.x[i] = Walker->node->x[i];
61 if (min.x[i] > Walker->node->x[i])
62 min.x[i] = Walker->node->x[i];
63 }
64 set->GoToNext();
65 }
66 cout << Verbose(2) << "Bounding box is " << min << " and " << max << "." << endl;
67
68 // 2. find then number of cells per axis
69 for (int i=0;i<NDIM;i++) {
70 N[i] = (int)floor((max.x[i] - min.x[i])/RADIUS)+1;
71 }
72 cout << Verbose(2) << "Number of cells per axis are " << N[0] << ", " << N[1] << " and " << N[2] << "." << endl;
73
74 // 3. allocate the lists
75 cout << Verbose(2) << "Allocating cells ... ";
76 if (LC != NULL) {
77 cout << Verbose(1) << "ERROR: Linked Cell list is already allocated, I do nothing." << endl;
78 return;
79 }
80 LC = new LinkedNodes[N[0]*N[1]*N[2]];
81 for (index=0;index<N[0]*N[1]*N[2];index++) {
82 LC [index].clear();
83 }
84 cout << "done." << endl;
85
86 // 4. put each atom into its respective cell
87 cout << Verbose(2) << "Filling cells ... ";
88 set->GoToFirst();
89 while (!set->IsEnd()) {
90 Walker = set->GetPoint();
91 for (int i=0;i<NDIM;i++) {
92 n[i] = (int)floor((Walker->node->x[i] - min.x[i])/RADIUS);
93 }
94 index = n[0] * N[1] * N[2] + n[1] * N[2] + n[2];
95 LC[index].push_back(Walker);
96 //cout << Verbose(2) << *Walker << " goes into cell " << n[0] << ", " << n[1] << ", " << n[2] << " with No. " << index << "." << endl;
97 set->GoToNext();
98 }
99 cout << "done." << endl;
100 cout << Verbose(1) << "End of LinkedCell" << endl;
101};
102
103
104/** Puts all atoms in \a *mol into a linked cell list with cell's lengths of \a RADIUS
105 * \param *set LCNodeSet class with all LCNode's
106 * \param RADIUS edge length of cells
107 */
108LinkedCell::LinkedCell(LinkedNodes *set, double radius)
109{
110 class TesselPoint *Walker = NULL;
111 RADIUS = radius;
112 LC = NULL;
113 for(int i=0;i<NDIM;i++)
114 N[i] = 0;
115 index = -1;
116 max.Zero();
117 min.Zero();
118 cout << Verbose(1) << "Begin of LinkedCell" << endl;
119 if (set->empty()) {
120 cerr << "ERROR: set contains no linked cell nodes!" << endl;
121 return;
122 }
123 // 1. find max and min per axis of atoms
124 LinkedNodes::iterator Runner = set->begin();
125 for (int i=0;i<NDIM;i++) {
126 max.x[i] = (*Runner)->node->x[i];
127 min.x[i] = (*Runner)->node->x[i];
128 }
129 for (LinkedNodes::iterator Runner = set->begin(); Runner != set->end(); Runner++) {
130 Walker = *Runner;
131 for (int i=0;i<NDIM;i++) {
132 if (max.x[i] < Walker->node->x[i])
133 max.x[i] = Walker->node->x[i];
134 if (min.x[i] > Walker->node->x[i])
135 min.x[i] = Walker->node->x[i];
136 }
137 }
138 cout << Verbose(2) << "Bounding box is " << min << " and " << max << "." << endl;
139
140 // 2. find then number of cells per axis
141 for (int i=0;i<NDIM;i++) {
142 N[i] = (int)floor((max.x[i] - min.x[i])/RADIUS)+1;
143 }
144 cout << Verbose(2) << "Number of cells per axis are " << N[0] << ", " << N[1] << " and " << N[2] << "." << endl;
145
146 // 3. allocate the lists
147 cout << Verbose(2) << "Allocating cells ... ";
148 if (LC != NULL) {
149 cout << Verbose(1) << "ERROR: Linked Cell list is already allocated, I do nothing." << endl;
150 return;
151 }
152 LC = new LinkedNodes[N[0]*N[1]*N[2]];
153 for (index=0;index<N[0]*N[1]*N[2];index++) {
154 LC [index].clear();
155 }
156 cout << "done." << endl;
157
158 // 4. put each atom into its respective cell
159 cout << Verbose(2) << "Filling cells ... ";
160 for (LinkedNodes::iterator Runner = set->begin(); Runner != set->end(); Runner++) {
161 Walker = *Runner;
162 for (int i=0;i<NDIM;i++) {
163 n[i] = (int)floor((Walker->node->x[i] - min.x[i])/RADIUS);
164 }
165 index = n[0] * N[1] * N[2] + n[1] * N[2] + n[2];
166 LC[index].push_back(Walker);
167 //cout << Verbose(2) << *Walker << " goes into cell " << n[0] << ", " << n[1] << ", " << n[2] << " with No. " << index << "." << endl;
168 }
169 cout << "done." << endl;
170 cout << Verbose(1) << "End of LinkedCell" << endl;
171};
172
173/** Destructor for class LinkedCell.
174 */
175LinkedCell::~LinkedCell()
176{
177 if (LC != NULL)
178 for (index=0;index<N[0]*N[1]*N[2];index++)
179 LC[index].clear();
180 delete[](LC);
181 for(int i=0;i<NDIM;i++)
182 N[i] = 0;
183 index = -1;
184 max.Zero();
185 min.Zero();
186};
187
188/** Checks whether LinkedCell::n[] is each within [0,N[]].
189 * \return if all in intervals - true, else -false
190 */
191bool LinkedCell::CheckBounds()
192{
193 bool status = true;
194 for(int i=0;i<NDIM;i++)
195 status = status && ((n[i] >=0) && (n[i] < N[i]));
196 if (!status)
197 cerr << "ERROR: indices are out of bounds!" << endl;
198 return status;
199};
200
201
202/** Returns a pointer to the current cell.
203 * \return LinkedAtoms pointer to current cell, NULL if LinkedCell::n[] are out of bounds.
204 */
205LinkedNodes* LinkedCell::GetCurrentCell()
206{
207 if (CheckBounds()) {
208 index = n[0] * N[1] * N[2] + n[1] * N[2] + n[2];
209 return (&(LC[index]));
210 } else {
211 return NULL;
212 }
213};
214
215/** Calculates the index for a given LCNode *Walker.
216 * \param *Walker LCNode to set index tos
217 * \return if the atom is also found in this cell - true, else - false
218 */
219bool LinkedCell::SetIndexToNode(const TesselPoint *Walker)
220{
221 bool status = false;
222 for (int i=0;i<NDIM;i++) {
223 n[i] = (int)floor((Walker->node->x[i] - min.x[i])/RADIUS);
224 }
225 index = n[0] * N[1] * N[2] + n[1] * N[2] + n[2];
226 if (CheckBounds()) {
227 for (LinkedNodes::iterator Runner = LC[index].begin(); Runner != LC[index].end(); Runner++)
228 status = status || ((*Runner) == Walker);
229 return status;
230 } else {
231 cerr << Verbose(1) << "ERROR: Node at " << *Walker << " is out of bounds." << endl;
232 return false;
233 }
234};
235
236/** Calculates the interval bounds of the linked cell grid.
237 * \param *lower lower bounds
238 * \param *upper upper bounds
239 */
240void LinkedCell::GetNeighbourBounds(int lower[NDIM], int upper[NDIM])
241{
242 for (int i=0;i<NDIM;i++) {
243 lower[i] = ((n[i]-1) >= 0) ? n[i]-1 : 0;
244 upper[i] = ((n[i]+1) < N[i]) ? n[i]+1 : N[i]-1;
245 //cout << " [" << Nlower[i] << "," << Nupper[i] << "] ";
246 // check for this axis whether the point is outside of our grid
247 if (n[i] < 0)
248 upper[i] = lower[i];
249 if (n[i] > N[i])
250 lower[i] = upper[i];
251
252 //cout << "axis " << i << " has bounds [" << lower[i] << "," << upper[i] << "]" << endl;
253 }
254};
255
256/** Calculates the index for a given Vector *x.
257 * \param *x Vector with coordinates
258 * \return Vector is inside bounding box - true, else - false
259 */
260bool LinkedCell::SetIndexToVector(const Vector *x)
261{
262 bool status = true;
263 for (int i=0;i<NDIM;i++) {
264 n[i] = (int)floor((x->x[i] - min.x[i])/RADIUS);
265 if (max.x[i] < x->x[i])
266 status = false;
267 if (min.x[i] > x->x[i])
268 status = false;
269 }
270 return status;
271};
272
Note: See TracBrowser for help on using the repository browser.