source: molecuilder/src/linkedcell.cpp@ 0ac84df

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

fixed indentation from tabs to two spaces.

  • Property mode set to 100644
File size: 4.4 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(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 index = n[0] * N[1] * N[2] + n[1] * N[2] + n[2];
141 if (CheckBounds()) {
142 for (LinkedAtoms::iterator Runner = LC[index].begin(); Runner != LC[index].end(); Runner++)
143 status = status || ((*Runner) == Walker);
144 return status;
145 } else {
146 cerr << Verbose(1) << "ERROR: Atom "<< *Walker << " at " << Walker->x << " is out of bounds." << endl;
147 return false;
148 }
149};
150
151/** Calculates the index for a given Vector *x.
152 * \param *x Vector with coordinates
153 * \return Vector is inside bounding box - true, else - false
154 */
155bool LinkedCell::SetIndexToVector(Vector *x)
156{
157 bool status = true;
158 for (int i=0;i<NDIM;i++) {
159 n[i] = (int)floor((x->x[i] - min.x[i])/RADIUS);
160 if (max.x[i] < x->x[i])
161 status = false;
162 if (min.x[i] > x->x[i])
163 status = false;
164 }
165 return status;
166};
167
Note: See TracBrowser for help on using the repository browser.