/** \file linkedcell.cpp * * Function implementations for the class LinkedCell. * */ #include "atom.hpp" #include "helpers.hpp" #include "linkedcell.hpp" #include "log.hpp" #include "molecule.hpp" #include "tesselation.hpp" #include "vector.hpp" // ========================================================= class LinkedCell =========================================== /** Constructor for class LinkedCell. */ LinkedCell::LinkedCell() { LC = NULL; for(int i=0;iIsEmpty()) { eLog() << Verbose(1) << "set contains no linked cell nodes!" << endl; return; } // 1. find max and min per axis of atoms set->GoToFirst(); Walker = set->GetPoint(); for (int i=0;inode->x[i]; min.x[i] = Walker->node->x[i]; } set->GoToFirst(); while (!set->IsEnd()) { Walker = set->GetPoint(); for (int i=0;inode->x[i]) max.x[i] = Walker->node->x[i]; if (min.x[i] > Walker->node->x[i]) min.x[i] = Walker->node->x[i]; } set->GoToNext(); } Log() << Verbose(2) << "Bounding box is " << min << " and " << max << "." << endl; // 2. find then number of cells per axis for (int i=0;iGoToFirst(); while (!set->IsEnd()) { Walker = set->GetPoint(); for (int i=0;inode->x[i] - min.x[i])/RADIUS); } index = n[0] * N[1] * N[2] + n[1] * N[2] + n[2]; LC[index].push_back(Walker); //Log() << Verbose(2) << *Walker << " goes into cell " << n[0] << ", " << n[1] << ", " << n[2] << " with No. " << index << "." << endl; set->GoToNext(); } Log() << Verbose(0) << "done." << endl; Log() << Verbose(1) << "End of LinkedCell" << endl; }; /** Puts all atoms in \a *mol into a linked cell list with cell's lengths of \a RADIUS * \param *set LCNodeSet class with all LCNode's * \param RADIUS edge length of cells */ LinkedCell::LinkedCell(LinkedNodes *set, const double radius) { class TesselPoint *Walker = NULL; RADIUS = radius; LC = NULL; for(int i=0;iempty()) { eLog() << Verbose(1) << "set contains no linked cell nodes!" << endl; return; } // 1. find max and min per axis of atoms LinkedNodes::iterator Runner = set->begin(); for (int i=0;inode->x[i]; min.x[i] = (*Runner)->node->x[i]; } for (LinkedNodes::iterator Runner = set->begin(); Runner != set->end(); Runner++) { Walker = *Runner; for (int i=0;inode->x[i]) max.x[i] = Walker->node->x[i]; if (min.x[i] > Walker->node->x[i]) min.x[i] = Walker->node->x[i]; } } Log() << Verbose(2) << "Bounding box is " << min << " and " << max << "." << endl; // 2. find then number of cells per axis for (int i=0;ibegin(); Runner != set->end(); Runner++) { Walker = *Runner; for (int i=0;inode->x[i] - min.x[i])/RADIUS); } index = n[0] * N[1] * N[2] + n[1] * N[2] + n[2]; LC[index].push_back(Walker); //Log() << Verbose(2) << *Walker << " goes into cell " << n[0] << ", " << n[1] << ", " << n[2] << " with No. " << index << "." << endl; } Log() << Verbose(0) << "done." << endl; Log() << Verbose(1) << "End of LinkedCell" << endl; }; /** Destructor for class LinkedCell. */ LinkedCell::~LinkedCell() { if (LC != NULL) for (index=0;index=0) && (n[i] < N[i])); if (!status) eLog() << Verbose(1) << "indices are out of bounds!" << endl; return status; }; /** Checks whether LinkedCell::n[] plus relative offset is each within [0,N[]]. * Note that for this check we don't admonish if out of bounds. * \param relative[NDIM] relative offset to current cell * \return if all in intervals - true, else -false */ bool LinkedCell::CheckBounds(const int relative[NDIM]) const { bool status = true; for(int i=0;i=0) && (n[i]+relative[i] < N[i])); return status; }; /** Returns a pointer to the current cell. * \return LinkedAtoms pointer to current cell, NULL if LinkedCell::n[] are out of bounds. */ const LinkedNodes* LinkedCell::GetCurrentCell() const { if (CheckBounds()) { index = n[0] * N[1] * N[2] + n[1] * N[2] + n[2]; return (&(LC[index])); } else { return NULL; } }; /** Returns a pointer to the current cell. * \param relative[NDIM] offset for each axis with respect to the current cell LinkedCell::n[NDIM] * \return LinkedAtoms pointer to current cell, NULL if LinkedCell::n[]+relative[] are out of bounds. */ const LinkedNodes* LinkedCell::GetRelativeToCurrentCell(const int relative[NDIM]) const { if (CheckBounds(relative)) { index = (n[0]+relative[0]) * N[1] * N[2] + (n[1]+relative[1]) * N[2] + (n[2]+relative[2]); return (&(LC[index])); } else { return NULL; } }; /** Calculates the index for a given LCNode *Walker. * \param *Walker LCNode to set index tos * \return if the atom is also found in this cell - true, else - false */ bool LinkedCell::SetIndexToNode(const TesselPoint * const Walker) const { bool status = false; for (int i=0;inode->x[i] - min.x[i])/RADIUS); } index = n[0] * N[1] * N[2] + n[1] * N[2] + n[2]; if (CheckBounds()) { for (LinkedNodes::iterator Runner = LC[index].begin(); Runner != LC[index].end(); Runner++) status = status || ((*Runner) == Walker); return status; } else { eLog() << Verbose(1) << "Node at " << *Walker << " is out of bounds." << endl; return false; } }; /** Calculates the interval bounds of the linked cell grid. * \param *lower lower bounds * \param *upper upper bounds */ void LinkedCell::GetNeighbourBounds(int lower[NDIM], int upper[NDIM]) const { for (int i=0;i= 0) ? n[i]-1 : 0; upper[i] = ((n[i]+1) < N[i]) ? n[i]+1 : N[i]-1; //Log() << Verbose(0) << " [" << Nlower[i] << "," << Nupper[i] << "] "; // check for this axis whether the point is outside of our grid if (n[i] < 0) upper[i] = lower[i]; if (n[i] > N[i]) lower[i] = upper[i]; //Log() << Verbose(0) << "axis " << i << " has bounds [" << lower[i] << "," << upper[i] << "]" << endl; } }; /** Calculates the index for a given Vector *x. * \param *x Vector with coordinates * \return Vector is inside bounding box - true, else - false */ bool LinkedCell::SetIndexToVector(const Vector * const x) const { bool status = true; for (int i=0;ix[i] - min.x[i])/RADIUS); if (max.x[i] < x->x[i]) status = false; if (min.x[i] > x->x[i]) status = false; } return status; };