source: src/LinkedCell/linkedcell.cpp@ b4f72c

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 b4f72c was 94d5ac6, checked in by Frederik Heber <heber@…>, 12 years ago

FIX: As we use GSL internally, we are as of now required to use GPL v2 license.

  • GNU Scientific Library is used at every place in the code, especially the sub-package LinearAlgebra is based on it which in turn is used really everywhere in the remainder of MoleCuilder. Hence, we have to use the GPL license for the whole of MoleCuilder. In effect, GPL's COPYING was present all along and stated the terms of the GPL v2 license.
  • Hence, I added the default GPL v2 disclaimer to every source file and removed the note about a (actually missing) LICENSE file.
  • also, I added a help-redistribute action which again gives the disclaimer of the GPL v2.
  • also, I changed in the disclaimer that is printed at every program start in builder_init.cpp.
  • TEST: Added check on GPL statement present in every module to test CodeChecks project-disclaimer.
  • Property mode set to 100644
File size: 12.2 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010-2012 University of Bonn. All rights reserved.
5 *
6 *
7 * This file is part of MoleCuilder.
8 *
9 * MoleCuilder is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * MoleCuilder is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23/** \file linkedcell.cpp
24 *
25 * Function implementations for the class LinkedCell_deprecated.
26 *
27 */
28
29// include config.h
30#ifdef HAVE_CONFIG_H
31#include <config.h>
32#endif
33
34#include "CodePatterns/MemDebug.hpp"
35
36#include "linkedcell.hpp"
37
38#include "Atom/atom.hpp"
39#include "CodePatterns/Verbose.hpp"
40#include "CodePatterns/Range.hpp"
41#include "CodePatterns/Log.hpp"
42#include "LinearAlgebra/Vector.hpp"
43#include "LinkedCell/IPointCloud.hpp"
44#include "molecule.hpp"
45#include "Tesselation/tesselation.hpp"
46
47// ========================================================= class LinkedCell_deprecated ===========================================
48
49/** Constructor for class LinkedCell_deprecated.
50 */
51LinkedCell_deprecated::LinkedCell_deprecated() :
52 LC(NULL),
53 RADIUS(0.),
54 index(-1)
55{
56 for(int i=0;i<NDIM;i++)
57 N[i] = 0;
58 max.Zero();
59 min.Zero();
60};
61
62/** Puts all atoms in \a *mol into a linked cell list with cell's lengths of \a RADIUS
63 * \param *set LCNodeSet class with all LCNode's
64 * \param RADIUS edge length of cells
65 */
66LinkedCell_deprecated::LinkedCell_deprecated(IPointCloud & set, const double radius) :
67 LC(NULL),
68 RADIUS(radius),
69 index(-1)
70{
71 TesselPoint *Walker = NULL;
72
73 for(int i=0;i<NDIM;i++)
74 N[i] = 0;
75 max.Zero();
76 min.Zero();
77 LOG(1, "Begin of LinkedCell");
78 if (set.IsEmpty()) {
79 ELOG(1, "set is NULL or contains no linked cell nodes!");
80 return;
81 }
82 // 1. find max and min per axis of atoms
83 set.GoToFirst();
84 Walker = set.GetPoint();
85 for (int i=0;i<NDIM;i++) {
86 max[i] = Walker->at(i);
87 min[i] = Walker->at(i);
88 }
89 set.GoToFirst();
90 while (!set.IsEnd()) {
91 Walker = set.GetPoint();
92 for (int i=0;i<NDIM;i++) {
93 if (max[i] < Walker->at(i))
94 max[i] = Walker->at(i);
95 if (min[i] > Walker->at(i))
96 min[i] = Walker->at(i);
97 }
98 set.GoToNext();
99 }
100 LOG(2, "Bounding box is " << min << " and " << max << ".");
101
102 // 2. find then number of cells per axis
103 for (int i=0;i<NDIM;i++) {
104 N[i] = static_cast<int>(floor((max[i] - min[i])/RADIUS)+1);
105 }
106 LOG(2, "Number of cells per axis are " << N[0] << ", " << N[1] << " and " << N[2] << ".");
107
108 // 3. allocate the lists
109 LOG(2, "INFO: Allocating cells ... ");
110 if (LC != NULL) {
111 ELOG(1, "Linked Cell list is already allocated, I do nothing.");
112 return;
113 }
114 ASSERT(N[0]*N[1]*N[2] < MAX_LINKEDCELLNODES, "Number linked of linked cell nodes exceded hard-coded limit, use greater edge length!");
115 LC = new TesselPointSTLList[N[0]*N[1]*N[2]];
116 for (index=0;index<N[0]*N[1]*N[2];index++) {
117 LC [index].clear();
118 }
119 LOG(0, "done.");
120
121 // 4. put each atom into its respective cell
122 LOG(2, "INFO: Filling cells ... ");
123 set.GoToFirst();
124 while (!set.IsEnd()) {
125 Walker = set.GetPoint();
126 for (int i=0;i<NDIM;i++) {
127 n[i] = static_cast<int>(floor((Walker->at(i) - min[i])/RADIUS));
128 }
129 index = n[0] * N[1] * N[2] + n[1] * N[2] + n[2];
130 LC[index].push_back(Walker);
131 //LOG(2, *Walker << " goes into cell " << n[0] << ", " << n[1] << ", " << n[2] << " with No. " << index << ".");
132 set.GoToNext();
133 }
134 LOG(0, "done.");
135 LOG(1, "End of LinkedCell");
136};
137
138
139/** Destructor for class LinkedCell_deprecated.
140 */
141LinkedCell_deprecated::~LinkedCell_deprecated()
142{
143 if (LC != NULL)
144 for (index=0;index<N[0]*N[1]*N[2];index++)
145 LC[index].clear();
146 delete[](LC);
147 for(int i=0;i<NDIM;i++)
148 N[i] = 0;
149 index = -1;
150};
151
152/** Checks whether LinkedCell_deprecated::n[] is each within [0,N[]].
153 * \return if all in intervals - true, else -false
154 */
155bool LinkedCell_deprecated::CheckBounds() const
156{
157 bool status = true;
158 for(int i=0;i<NDIM;i++)
159 status = status && ((n[i] >=0) && (n[i] < N[i]));
160// if (!status)
161// ELOG(1, "indices are out of bounds!");
162 return status;
163};
164
165/** Checks whether LinkedCell_deprecated::n[] plus relative offset is each within [0,N[]].
166 * Note that for this check we don't admonish if out of bounds.
167 * \param relative[NDIM] relative offset to current cell
168 * \return if all in intervals - true, else -false
169 */
170bool LinkedCell_deprecated::CheckBounds(const int relative[NDIM]) const
171{
172 bool status = true;
173 for(int i=0;i<NDIM;i++)
174 status = status && ((n[i]+relative[i] >=0) && (n[i]+relative[i] < N[i]));
175 return status;
176};
177
178
179/** Returns a pointer to the current cell.
180 * \return LinkedAtoms pointer to current cell, NULL if LinkedCell_deprecated::n[] are out of bounds.
181 */
182const TesselPointSTLList* LinkedCell_deprecated::GetCurrentCell() const
183{
184 if (CheckBounds()) {
185 index = n[0] * N[1] * N[2] + n[1] * N[2] + n[2];
186 return (&(LC[index]));
187 } else {
188 return NULL;
189 }
190};
191
192/** Returns a pointer to the current cell.
193 * \param relative[NDIM] offset for each axis with respect to the current cell LinkedCell_deprecated::n[NDIM]
194 * \return LinkedAtoms pointer to current cell, NULL if LinkedCell_deprecated::n[]+relative[] are out of bounds.
195 */
196const TesselPointSTLList* LinkedCell_deprecated::GetRelativeToCurrentCell(const int relative[NDIM]) const
197{
198 if (CheckBounds(relative)) {
199 index = (n[0]+relative[0]) * N[1] * N[2] + (n[1]+relative[1]) * N[2] + (n[2]+relative[2]);
200 return (&(LC[index]));
201 } else {
202 return NULL;
203 }
204};
205
206/** Set the index to the cell containing a given Vector *x.
207 * \param *x Vector with coordinates
208 * \return Vector is inside bounding box - true, else - false
209 */
210bool LinkedCell_deprecated::SetIndexToVector(const Vector & x) const
211{
212 for (int i=0;i<NDIM;i++)
213 n[i] = (int)floor((x.at(i) - min[i])/RADIUS);
214
215 return CheckBounds();
216};
217
218/** Calculates the index for a given LCNode *Walker.
219 * \param *Walker LCNode to set index tos
220 * \return if the atom is also found in this cell - true, else - false
221 */
222bool LinkedCell_deprecated::SetIndexToNode(const TesselPoint * const Walker) const
223{
224 bool status = false;
225 for (int i=0;i<NDIM;i++) {
226 n[i] = static_cast<int>(floor((Walker->at(i) - min[i])/RADIUS));
227 }
228 index = n[0] * N[1] * N[2] + n[1] * N[2] + n[2];
229 if (CheckBounds()) {
230 for (TesselPointSTLList::iterator Runner = LC[index].begin(); Runner != LC[index].end(); Runner++)
231 status = status || ((*Runner) == Walker);
232 return status;
233 } else {
234 ELOG(1, "Node at " << *Walker << " is out of bounds.");
235 return false;
236 }
237};
238
239/** Calculates the interval bounds of the linked cell grid.
240 * \param lower lower bounds
241 * \param upper upper bounds
242 * \param step how deep to check the neighbouring cells (i.e. number of layers to check)
243 */
244void LinkedCell_deprecated::GetNeighbourBounds(int lower[NDIM], int upper[NDIM], int step) const
245{
246 for (int i=0;i<NDIM;i++) {
247 lower[i] = n[i]-step;
248 if (lower[i] < 0)
249 lower[i] = 0;
250 if (lower[i] >= N[i])
251 lower[i] = N[i]-1;
252 upper[i] = n[i]+step;
253 if (upper[i] >= N[i])
254 upper[i] = N[i]-1;
255 if (upper[i] < 0)
256 upper[i] = 0;
257 //LOG(0, "axis " << i << " has bounds [" << lower[i] << "," << upper[i] << "]");
258 }
259};
260
261/** Returns a list with all neighbours from the current LinkedCell_deprecated::index.
262 * \param distance (if no distance, then adjacent cells are taken)
263 * \return list of tesselpoints
264 */
265TesselPointSTLList* LinkedCell_deprecated::GetallNeighbours(const double distance) const
266{
267 int Nlower[NDIM], Nupper[NDIM];
268 TesselPoint *Walker = NULL;
269 TesselPointSTLList *TesselList = new TesselPointSTLList;
270
271 // then go through the current and all neighbouring cells and check the contained points for possible candidates
272 const int step = (distance == 0) ? 1 : (int)floor(distance/RADIUS + 1.);
273 GetNeighbourBounds(Nlower, Nupper, step);
274
275 for (n[0] = Nlower[0]; n[0] <= Nupper[0]; n[0]++)
276 for (n[1] = Nlower[1]; n[1] <= Nupper[1]; n[1]++)
277 for (n[2] = Nlower[2]; n[2] <= Nupper[2]; n[2]++) {
278 const TesselPointSTLList *List = GetCurrentCell();
279 //LOG(1, "Current cell is " << n[0] << ", " << n[1] << ", " << n[2] << " with No. " << index << ".");
280 if (List != NULL) {
281 for (TesselPointSTLList::const_iterator Runner = List->begin(); Runner != List->end(); Runner++) {
282 Walker = *Runner;
283 TesselList->push_back(Walker);
284 }
285 }
286 }
287 return TesselList;
288};
289
290/** Set the index to the cell containing a given Vector *x, which is not inside the LinkedCell_deprecated's domain
291 * Note that as we have to check distance from every corner of the closest cell, this function is faw more
292 * expensive and if Vector is known to be inside LinkedCell_deprecated's domain, then SetIndexToVector() should be used.
293 * \param *x Vector with coordinates
294 * \return minimum squared distance of cell to given vector (if inside of domain, distance is 0)
295 */
296double LinkedCell_deprecated::SetClosestIndexToOutsideVector(const Vector * const x) const
297{
298 for (int i=0;i<NDIM;i++) {
299 n[i] = (int)floor((x->at(i) - min[i])/RADIUS);
300 if (n[i] < 0)
301 n[i] = 0;
302 if (n[i] >= N[i])
303 n[i] = N[i]-1;
304 }
305
306 // calculate distance of cell to vector
307 double distanceSquared = 0.;
308 bool outside = true; // flag whether x is found in- or outside of LinkedCell_deprecated's domain/closest cell
309 Vector corner; // current corner of closest cell
310 Vector tester; // Vector pointing from corner to center of closest cell
311 Vector Distance; // Vector from corner of closest cell to x
312
313 Vector center; // center of the closest cell
314 for (int i=0;i<NDIM;i++)
315 center[i] = min[i]+((double)n[i]+.5)*RADIUS;
316
317 int c[NDIM];
318 for (c[0]=0;c[0]<=1;c[0]++)
319 for (c[1]=0; c[1]<=1;c[1]++)
320 for (c[2]=0; c[2]<=1;c[2]++) {
321 // set up corner
322 for (int i=0;i<NDIM;i++)
323 corner[i] = min[i]+RADIUS*((double)n[i]+c[i]);
324 // set up distance vector
325 Distance = (*x) - corner;
326 const double dist = Distance.NormSquared();
327 // check whether distance is smaller
328 if (dist< distanceSquared)
329 distanceSquared = dist;
330 // check whether distance vector goes inside or outside
331 tester = center -corner;
332 if (tester.ScalarProduct(Distance) < 0)
333 outside = false;
334 }
335 return (outside ? distanceSquared : 0.);
336};
337
338/** Returns a list of all TesselPoint with distance less than \a radius to \a *Center.
339 * \param radius radius of sphere
340 * \param *center center of sphere
341 * \return list of all points inside sphere
342 */
343TesselPointSTLList* LinkedCell_deprecated::GetPointsInsideSphere(const double radius, const Vector * const center) const
344{
345 const double radiusSquared = radius*radius;
346 TesselPoint *Walker = NULL;
347 TesselPointSTLList *TesselList = new TesselPointSTLList;
348 TesselPointSTLList *NeighbourList = NULL;
349
350 // set index of LC to center of sphere
351 const double dist = SetClosestIndexToOutsideVector(center);
352 if (dist > 2.*radius) {
353 ELOG(1, "Vector " << *center << " is too far away from any atom in LinkedCell's bounding box.");
354 return TesselList;
355 } else
356 LOG(3, "DEBUG: Distance of closest cell to center of sphere with radius " << radius << " is " << dist << ".");
357
358 // gather all neighbours first, then look who fulfills distance criteria
359 NeighbourList = GetallNeighbours(2.*radius-dist);
360 //LOG(1, "I found " << NeighbourList->size() << " neighbours to check.");
361 if (NeighbourList != NULL) {
362 for (TesselPointSTLList::const_iterator Runner = NeighbourList->begin(); Runner != NeighbourList->end(); Runner++) {
363 Walker = *Runner;
364 //LOG(1, "Current neighbour is at " << *Walker->node << ".");
365 if ((Walker->DistanceSquared(*center) - radiusSquared) < MYEPSILON) {
366 TesselList->push_back(Walker);
367 }
368 }
369 delete(NeighbourList);
370 } else
371 ELOG(2, "Around vector " << *center << " there are no atoms.");
372 return TesselList;
373};
Note: See TracBrowser for help on using the repository browser.