// -*- C++ -*-
// NeighborCellLocator.h: Cell-based algorithm for finding neighbors.
//
// Copyright (C) 2008-2011 Jakob Schiotz and Center for Individual
// Nanoparticle Functionality, Department of Physics, Technical
// University of Denmark. Email: schiotz@fysik.dtu.dk
//
// This file is part of Asap version 3.
// Asap is released under the GNU Lesser Public License (LGPL) version 3.
// However, the parts of Asap distributed within the OpenKIM project
// (including this file) are also released under the Common Development
// and Distribution License (CDDL) version 1.0.
//
// This program is free software: you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License
// version 3 as published by the Free Software Foundation. Permission
// to use other versions of the GNU Lesser General Public License may
// granted by Jakob Schiotz or the head of department of the
// Department of Physics, Technical University of Denmark, as
// described in section 14 of the GNU General Public License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// and the GNU Lesser Public License along with this program. If not,
// see .
#ifndef NEIGHBORCELLLOCATOR
#define NEIGHBORCELLLOCATOR
#include "AsapPython.h"
#include "Asap.h"
#include "Vec.h"
#include "NeighborLocator.h"
#include "IVec.h"
#include "Templates.h"
#include
using std::vector;
#include
using std::pair;
#include
namespace ASAPSPACE {
//typedef unsigned char translationsidx_t; // Could also be int
typedef int translationsidx_t; // Could also be unsigned char
//typedef long translationsidx_t; // Silly!
PyAsap_NeighborLocatorObject *PyAsap_NewNeighborCellLocator(Atoms *a,
double rCut, double driftfactor = 0.05, bool slave = false);
class NeighborCellLocator : public NeighborLocator
{
protected:
/// Generate a neighbor list for atoms a with cutoff rCut.
/// The neighbor list will contain all neighbors within the distance
/// rCut. The neighborlist can be reused until an atom has moved
/// more than rCut*driftfactor. The slave parameter is set to true
/// if this NeighborCellLocator is used to help building another
/// NeighborLocator, it suppresses the code that would otherwise
/// trigger migrations in parallel simulations.
NeighborCellLocator(Atoms *a, double rCut, double driftfactor = 0.05,
bool slave = false);
virtual ~NeighborCellLocator();
friend PyAsap_NeighborLocatorObject *PyAsap_NewNeighborCellLocator(
Atoms *a, double rCut, double driftfactor, bool slave);
friend void PyAsap_Dealloc(PyObject *self);
public:
/// Check if the neighbor list can still be reused, update if not.
bool CheckAndUpdateNeighborList();
/// Check if the neighbor list can still be reused, update if not.
///
/// This version is used when called from Python
virtual bool CheckAndUpdateNeighborList(PyObject *atoms);
/// Check the neighbor list.
///
/// Check if the neighbor list can still be reused, return true if
/// it should be updated.
virtual bool CheckNeighborList();
/// Update neighbor list
virtual void UpdateNeighborList();
/// Get wrapped positions of all the atoms
const vector &GetWrappedPositions() const {assert(wrappedPositionsValid);
return wrappedPositions;}
void GetWrappedPositions(vector &wp) const {assert(wrappedPositionsValid);
wp.insert(wp.begin(), wrappedPositions.begin(), wrappedPositions.end());}
/// Get scaled positions of all the atoms
const vector &GetScaledPositions() const;
/// Get reference positions (used by NeighborList)
const Vec *GetReferencePositions() const {return &referencePositions[0];}
/// Get information about the neighbors of atom n ("half" neighbor list)
///
/// Input values: n is the number of the atom. r (optional) is a
/// cutoff, must be less than rCut in the constructor (not
/// checked!).
///
/// In-out values: size contains the maximum space in the arrays.
/// It is decremented by the number of neighbors placed in the
/// arrays. It is an error to call GetNeighbors with too small a
/// value of size.
///
/// Out values: neighbors[] contains the numbers of the atoms,
/// diffs[] contains the \em relative positions of the atoms,
/// diffs2[] contains the norms of the diffs vectors.
///
/// Return value: The number of neighbors.
int GetNeighbors(int n, int *neighbors, Vec *diffs, double *diffs2,
int& size, double r = -1.0) const;
/// Get information about the neighbors of atom n ("half" neighbor list)
///
/// This version of GetNeighbors only returns the numbers of the neighbors.
/// It is intended for the Python interface.
void GetNeighbors(int n, vector &neighbors) const;
int GetFullNeighbors(int n, int *neighbors, Vec *diffs, double *diffs2,
int& size, double r = -1.0) const;
/// Get information about the neighbors of atom n (full neighbor list)
///
/// This version of GetNeighbors only returns the numbers of the neighbors.
/// It is intended for the Python interface.
void GetFullNeighbors(int n, vector &neighbors) const;
/// Return the neighbors and the corresponding translations.
///
/// The vectors are cleared before data is put into them.
///
/// Return value: The number of neighbors.
#if 0
int GetListAndTranslations(int n, vector &neighbors,
vector &translations) const;
#endif
int GetListAndTranslations(int n, vector< pair >
&neighbors) const;
int GetComplementaryListAndTranslations(int n,
vector< pair >
&neighbors) const;
/// Remake neighbor lists when a few atoms have been modified.
///
/// This version, unlike NeighborList::RemakeList does
/// not report back which other atoms have been affected.
void RemakeLists_Simple(const set &modified);
/// Return the guaranteed maximal length of a single atom's NB list.
/// Call this before using GetNeighbors() to make sure the arrays
/// are big enough. The value may change when the neighbor list is
/// updated.
int MaxNeighborListLength() const {return maxLength;}
/// Get the number of atoms in the corresponding list of atoms.
int GetNumberOfAtoms() const {return nAtoms;} // Used from swig.
/// Return the cutoff distance (rCut) specified when creating this nblist.
double GetCutoffRadius() const {return rCut;}
/// Return the cutoff distance including twice the drift.
double GetCutoffRadiusWithDrift() const {
throw AsapError("NeighborCellLocator cannot predict its drift radius.");}
/// Get a copy of the table of translations (27 entries)
void GetTranslationTable(vector &table) const;
/// Normalize the positions and calculate scaled space version
///
/// This is used when a neighbor list is updated
void ScaleAndNormalizePositions();
/// Normalize some positions and calculate scaled space version
///
/// The first argument is a set of atoms to be normalized, the
/// corresponding scaled positions are placed in scaledpos.
void ScaleAndNormalizePositions(const set &modified,
vector &scaledpos);
/// Normalizing new positions using the normalization already calculated.
///
/// This is used when checking a neighborlist.
void RenormalizePositions();
#if 0
/// Renormalize the old positions using old and new positions of the atoms.
///
/// This is called by a master neighbor list when it has normalized
/// the positions of the atoms. The argument is the positions of
/// the atoms *before* renormalization, this method uses them
/// together with the current positions to update its own list of
/// old positions.
void RenormalizeReferencePositions(const vector &oldpos);
#endif
/// Update reference positions of some atoms
void UpdateReferencePositions(const set &modified);
/// Return the atoms access object. Used by a few tool functions.
virtual Atoms *GetAtoms() const {return atoms;}
string GetName() const {return "NeighborCellLocator";}
/// Print internal info about an atom
virtual void print_info(int n);
/// Print memory usage
virtual long PrintMemory() const;
protected:
/// Generate a new neighbor list.
virtual void MakeList();
/// Make the lists of neighboring cells.
void MakeNeighboringCellLists();
/// Make translation table
void MakeTranslationTable();
typedef vector > nbcell_t;
const nbcell_t &makeNbCells(int thiscell, nbcell_t &NbCells) const;
int CommonGetNeighbors(int n, int *neighbors, Vec *diffs, double *diffs2,
int& size, double r, bool wantfull) const;
void CommonGetNeighbors(int a1, vector &neighbors,
bool wantfull) const;
double get_drift() const;
protected:
Atoms *atoms; ///< A pointer to the atoms.
int nAtoms; ///< The number of atoms excluding ghosts.
int nAllAtoms; ///< The number of atoms including ghosts.
double rCut; ///< The cutoff radius.
double rCut2; ///< The square of the cutoff radius.
double minboxsize; ///< The minimal box size
bool periodic[3]; ///< The boundary conditions.
bool oldperiodic[3]; ///< The boundary conditions at the last update.
int maxLength; ///< The guaranteed max length of a neighbor list.
int nCells[3]; ///< Number of cells
int nTotalCells[4];
int nCellsTrue[3];
int nCellsGapStart[3];
int nCellsGapSize[3];
bool slave; ///< This locator is slave of another one.
double size[3]; ///< Size of system in scaled space
double minimum[3]; ///< Offset of system in scaled space
vector referencePositions; ///< Positions at last update.
vector wrappedPositions; ///< Wrapped positions.
vector scaledPositions; ///< Scaled positions.
vector offsetPositions; ///< wrappedPositions - positions.
vector scaledOffsetPositions;
bool scaledPositionsValid;
bool wrappedPositionsValid;
Vec old_inverse_cell[3]; ///< Inverse unit cell of last renormalization.
int supercell_counter; ///< When was old_inverse_cell last updated?
/// The list of cells containing the atoms
vector< vector > cells;
/// The number of the cell to which an atom belongs
vector cellIndices;
/// For each cell, a list of the neighboring cells, and their offset
/// across the periodic boundaries.
vector neighborCellOffsets;
/// List of neighboring cells, valid for a cell not touching the boundary.
nbcell_t nbCells_inside;
nbcell_t nbCells_left;
nbcell_t nbCells_right;
nbcell_t nbCells_top;
nbcell_t nbCells_bottom;
nbcell_t nbCells_front;
nbcell_t nbCells_back;
/// Table of possible translation vectors
vector translationTable;
};
} // end namespace
#endif // NEIGHBORCELLLOCATOR