Ignore:
Timestamp:
Apr 12, 2010, 4:25:50 PM (15 years ago)
Author:
Frederik Heber <heber@…>
Children:
a732ff
Parents:
f7e187
Message:

BUGFIX: LinkedCell::GetPointsInsideSphere() did not work if center of sphere was outside of LinkedCell's domain.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • molecuilder/src/linkedcell.cpp

    rf7e187 r41c00d  
    337337};
    338338
     339/** Set the index to the cell containing a given Vector *x, which is not inside the LinkedCell's domain
     340 * Note that as we have to check distance from every corner of the closest cell, this function is faw more
     341 * expensive and if Vector is known to be inside LinkedCell's domain, then SetIndexToVector() should be used.
     342 * \param *x Vector with coordinates
     343 * \return minimum squared distance of cell to given vector (if inside of domain, distance is 0)
     344 */
     345double LinkedCell::SetClosestIndexToOutsideVector(const Vector * const x) const
     346{
     347  for (int i=0;i<NDIM;i++) {
     348    n[i] = (int)floor((x->x[i] - min.x[i])/RADIUS);
     349    if (n[i] < 0)
     350      n[i] = 0;
     351    if (n[i] >= N[i])
     352      n[i] = N[i]-1;
     353  }
     354
     355  // calculate distance of cell to vector
     356  double distanceSquared = 0.;
     357  bool outside = true;  // flag whether x is found in- or outside of LinkedCell's domain/closest cell
     358  Vector corner; // current corner of closest cell
     359  Vector tester; // Vector pointing from corner to center of closest cell
     360  Vector Distance;  // Vector from corner of closest cell to x
     361
     362  Vector center;  // center of the closest cell
     363  for (int i=0;i<NDIM;i++)
     364    center.x[i] = min.x[i]+((double)n[i]+.5)*RADIUS;
     365
     366  int c[NDIM];
     367  for (c[0]=0;c[0]<=1;c[0]++)
     368    for (c[1]=0; c[1]<=1;c[1]++)
     369      for (c[2]=0; c[2]<=1;c[2]++) {
     370        // set up corner
     371        for (int i=0;i<NDIM;i++)
     372          corner.x[i] = min.x[i]+RADIUS*((double)n[i]+c[i]);
     373        // set up distance vector
     374        Distance.CopyVector(x);
     375        Distance.SubtractVector(&corner);
     376        const double dist = Distance.NormSquared();
     377        // check whether distance is smaller
     378        if (dist< distanceSquared)
     379          distanceSquared = dist;
     380        // check whether distance vector goes inside or outside
     381        tester.CopyVector(&center);
     382        tester.SubtractVector(&corner);
     383        if (tester.ScalarProduct(&Distance) < 0)
     384          outside = false;
     385      }
     386  return (outside ? distanceSquared : 0.);
     387};
    339388
    340389/** Returns a list of all TesselPoint with distance less than \a radius to \a *Center.
     
    351400
    352401  // set index of LC to center of sphere
    353   if (!SetIndexToVector(center)) {
    354     DoeLog(1) && (eLog()<< Verbose(1) << "Vector " << *center << " is outside of LinkedCell's bounding box." << endl);
     402  const double dist = SetClosestIndexToOutsideVector(center);
     403  if (dist > radius) {
     404    DoeLog(1) && (eLog()<< Verbose(1) << "Vector " << *center << " is too far away from any atom in LinkedCell's bounding box." << endl);
    355405    return TesselList;
    356406  }
    357407
    358408  // gather all neighbours first, then look who fulfills distance criteria
    359   NeighbourList = GetallNeighbours(radius);
     409  NeighbourList = GetallNeighbours(radius-dist);
    360410  if (NeighbourList != NULL) {
    361411    for (LinkedNodes::const_iterator Runner = NeighbourList->begin(); Runner != NeighbourList->end(); Runner++) {
Note: See TracChangeset for help on using the changeset viewer.