source: src/linkedcell.cpp@ 8cd903

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since 8cd903 was 8cd903, 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.