| 1 | /* | 
|---|
| 2 | * Project: MoleCuilder | 
|---|
| 3 | * Description: creates and alters molecular systems | 
|---|
| 4 | * Copyright (C)  2010 University of Bonn. All rights reserved. | 
|---|
| 5 | * Please see the LICENSE file or "Copyright notice" in builder.cpp for details. | 
|---|
| 6 | */ | 
|---|
| 7 |  | 
|---|
| 8 | /** | 
|---|
| 9 | * \file linkedcell.dox | 
|---|
| 10 | * | 
|---|
| 11 | * Created on: Nov 15, 2011 | 
|---|
| 12 | *    Author: heber | 
|---|
| 13 | */ | 
|---|
| 14 |  | 
|---|
| 15 | /** \page linkedcell Linked Cell structure | 
|---|
| 16 | * | 
|---|
| 17 | *  The linked cell ansatz is used to obtain neighborhoods of particles in | 
|---|
| 18 | *  \f${\cal R}^3\f$ more quickly than in \f${\cal O}(N^2)\f$ if \f$ N \f$ is | 
|---|
| 19 | *  the number of particles. We require a maximum length, beyond which no more | 
|---|
| 20 | *  neighbors are sought. With this length we place a mesh on top of our space | 
|---|
| 21 | *  and associate each particle with a specific cell in this three-dimensional | 
|---|
| 22 | *  mesh, i.e. per cell we have a linked list containing references to all | 
|---|
| 23 | *  particles that are located in this cell (i.e. whose coordinates are bounded | 
|---|
| 24 | *  from above and below per coordinate axis by the cell's intervals). Eventually | 
|---|
| 25 | *  this allows for a complexity of \f${\cal O}(N \log N)\f$. | 
|---|
| 26 | * | 
|---|
| 27 | *  \section linkedcell-structure Code structure | 
|---|
| 28 | * | 
|---|
| 29 | *  The code is structured as a Model-View-Controller ansatz. The reason is as | 
|---|
| 30 | *  follows: The required edge length is not known at compilation but is a | 
|---|
| 31 | *  value depending on run-time variables. However, we must not re-initiate a | 
|---|
| 32 | *  linked cell structure whenever a slightly different edge length is requested. | 
|---|
| 33 | *  Instead we may use an already present linked cell instance that more or | 
|---|
| 34 | *  less (via some heuristic) matches the desired edge length. This slightly | 
|---|
| 35 | *  degrades asymptotic performance but enhances pre-asymptotics because we | 
|---|
| 36 | *  don't have to re-build a linked cell instance each and every time. | 
|---|
| 37 | * | 
|---|
| 38 | *  We briefly explain | 
|---|
| 39 | *  each part: | 
|---|
| 40 | *  -# \link LinkedCell_Model Model\endlink: | 
|---|
| 41 | *    The model represents a certain representation of the data( here a | 
|---|
| 42 | *    specific edge length), i.e. it is a specific instantiation of a linked | 
|---|
| 43 | *    cell structure. | 
|---|
| 44 | *  -# \link LinkedCell_Controller Controller\endlink: | 
|---|
| 45 | *    The controller contains the heuristic criterion and all | 
|---|
| 46 | *    present linked cell instances. It decides when new ones are required and | 
|---|
| 47 | *    when old ones are no longer needed. | 
|---|
| 48 | *  -# \link LinkedCell_View View\endlink: | 
|---|
| 49 | *    The view is the interface of the whole to the outside, here the | 
|---|
| 50 | *    user requests high-level functions, such as getAllNeighbours. How these | 
|---|
| 51 | *    are then performed is none-of-his-business but encapsulated below. | 
|---|
| 52 | * | 
|---|
| 53 | * This ansatz makes it possible to even implemented k-Nearest-Neighbor trees | 
|---|
| 54 | * instead of a linked cell ansatz if it is more convenient (e.g. if constant | 
|---|
| 55 | * updates are required). A single cell of the linked cell array is implemented | 
|---|
| 56 | * in LinkedCell for greater convenience, e.g. we store the array indices there | 
|---|
| 57 | * and may add further commodity functions. | 
|---|
| 58 | * | 
|---|
| 59 | * | 
|---|
| 60 | * \section linkedcell-howto How to use the code | 
|---|
| 61 | * | 
|---|
| 62 | * In this section we explain how you, as the user, is supposed to use the code. | 
|---|
| 63 | * | 
|---|
| 64 | * The following snippet gives you access to the linked cell interface. | 
|---|
| 65 | * \code | 
|---|
| 66 | LinkedCell_View &interface = World::getInstance().getLinkedCell(double distance); | 
|---|
| 67 | * \endcode | 
|---|
| 68 | * where distance is the desired edge length for the linked cell construct (e.g. | 
|---|
| 69 | * the maximum distance where you want neighbors to be returned). | 
|---|
| 70 | * | 
|---|
| 71 | * Now, you can access its functions as simply as | 
|---|
| 72 | * \code | 
|---|
| 73 | LinkedList &list = interface.getAllNeighbours(4., Vector(0.,0.,0.)); | 
|---|
| 74 | * \endcode | 
|---|
| 75 | * which returns a LinkedList, i.e. a set of points, that reside in a sphere | 
|---|
| 76 | * around the origin of radius 4. where the boundary conditions apply as are | 
|---|
| 77 | * current in the Box stored in the World: | 
|---|
| 78 | * \code | 
|---|
| 79 | World::getInstance().getDomain() | 
|---|
| 80 | * \endcode | 
|---|
| 81 | * | 
|---|
| 82 | * You can iterate over the LinkedList as follows: | 
|---|
| 83 | * \code | 
|---|
| 84 | if (!ListOfNeighbors.empty()) { | 
|---|
| 85 | // we have some possible candidates, go through each | 
|---|
| 86 | for (LinkedCell::LinkedList::const_iterator neighboriter = ListOfNeighbors.begin(); | 
|---|
| 87 | neighboriter != ListOfNeighbors.end(); | 
|---|
| 88 | ++neighboriter) { | 
|---|
| 89 | const atom * const OtherWalker = dynamic_cast<const atom *>(*neighboriter); | 
|---|
| 90 | ASSERT(OtherWalker != NULL, | 
|---|
| 91 | "__func__ - TesselPoint " | 
|---|
| 92 | +(*neighboriter)->getName()+" that was not an atom retrieved from LinkedList"); | 
|---|
| 93 | ... | 
|---|
| 94 |  | 
|---|
| 95 | } | 
|---|
| 96 | } | 
|---|
| 97 | * \endcode | 
|---|
| 98 | * Note that we dynamically cast the TesselPoint to its more involved class atom which is | 
|---|
| 99 | * in general ok as only atoms are contained in LinkedCell constructs. | 
|---|
| 100 | * | 
|---|
| 101 | * \date 2011-11-30 | 
|---|
| 102 | * | 
|---|
| 103 | */ | 
|---|