source: src/linkedcell.cpp@ d04966

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 d04966 was 1999d8, checked in by Frederik Heber <heber@…>, 16 years ago

BUGFIX: PointCloud implementation in molecule stopped one before last, IsLast() -> IsEnd()

  • Property mode set to 100644
File size: 5.4 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/** Destructor for class LinkedCell.
104 */
105LinkedCell::~LinkedCell()
106{
107 if (LC != NULL)
108 for (index=0;index<N[0]*N[1]*N[2];index++)
109 LC[index].clear();
110 delete[](LC);
111 for(int i=0;i<NDIM;i++)
112 N[i] = 0;
113 index = -1;
114 max.Zero();
115 min.Zero();
116};
117
118/** Checks whether LinkedCell::n[] is each within [0,N[]].
119 * \return if all in intervals - true, else -false
120 */
121bool LinkedCell::CheckBounds()
122{
123 bool status = true;
124 for(int i=0;i<NDIM;i++)
125 status = status && ((n[i] >=0) && (n[i] < N[i]));
126 if (!status)
127 cerr << "ERROR: indices are out of bounds!" << endl;
128 return status;
129};
130
131
132/** Returns a pointer to the current cell.
133 * \return LinkedAtoms pointer to current cell, NULL if LinkedCell::n[] are out of bounds.
134 */
135LinkedNodes* LinkedCell::GetCurrentCell()
136{
137 if (CheckBounds()) {
138 index = n[0] * N[1] * N[2] + n[1] * N[2] + n[2];
139 return (&(LC[index]));
140 } else {
141 return NULL;
142 }
143};
144
145/** Calculates the index for a given LCNode *Walker.
146 * \param *Walker LCNode to set index tos
147 * \return if the atom is also found in this cell - true, else - false
148 */
149bool LinkedCell::SetIndexToNode(const TesselPoint *Walker)
150{
151 bool status = false;
152 for (int i=0;i<NDIM;i++) {
153 n[i] = (int)floor((Walker->node->x[i] - min.x[i])/RADIUS);
154 }
155 index = n[0] * N[1] * N[2] + n[1] * N[2] + n[2];
156 if (CheckBounds()) {
157 for (LinkedNodes::iterator Runner = LC[index].begin(); Runner != LC[index].end(); Runner++)
158 status = status || ((*Runner) == Walker);
159 return status;
160 } else {
161 cerr << Verbose(1) << "ERROR: Node at " << *Walker << " is out of bounds." << endl;
162 return false;
163 }
164};
165
166/** Calculates the interval bounds of the linked cell grid.
167 * \param *lower lower bounds
168 * \param *upper upper bounds
169 */
170void LinkedCell::GetNeighbourBounds(int lower[NDIM], int upper[NDIM])
171{
172 for (int i=0;i<NDIM;i++) {
173 lower[i] = ((n[i]-1) >= 0) ? n[i]-1 : 0;
174 upper[i] = ((n[i]+1) < N[i]) ? n[i]+1 : N[i]-1;
175 //cout << " [" << Nlower[i] << "," << Nupper[i] << "] ";
176 // check for this axis whether the point is outside of our grid
177 if (n[i] < 0)
178 upper[i] = lower[i];
179 if (n[i] > N[i])
180 lower[i] = upper[i];
181
182 //cout << "axis " << i << " has bounds [" << lower[i] << "," << upper[i] << "]" << endl;
183 }
184};
185
186/** Calculates the index for a given Vector *x.
187 * \param *x Vector with coordinates
188 * \return Vector is inside bounding box - true, else - false
189 */
190bool LinkedCell::SetIndexToVector(const Vector *x)
191{
192 bool status = true;
193 for (int i=0;i<NDIM;i++) {
194 n[i] = (int)floor((x->x[i] - min.x[i])/RADIUS);
195 if (max.x[i] < x->x[i])
196 status = false;
197 if (min.x[i] > x->x[i])
198 status = false;
199 }
200 return status;
201};
202
Note: See TracBrowser for help on using the repository browser.