// -*- C++ -*- // NeighborList.h: The main neighbor list object. // // Copyright (C) 2001-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 NEIGHBORLIST2 #define NEIGHBORLIST2 #include "AsapPython.h" #include "Asap.h" #include "NeighborLocator.h" #include "NeighborCellLocator.h" #include "IVec.h" #include "Templates.h" #include using std::vector; #include using std::pair; #include #include namespace ASAPSPACE { PyAsap_NeighborLocatorObject *PyAsap_NewNeighborList(Atoms *atoms, double rCut, double driftfactor); class NeighborList : 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. NeighborList(Atoms *a, double rCut, double driftfactor); virtual ~NeighborList(); friend ASAPSPACE::PyAsap_NeighborLocatorObject *PyAsap_NewNeighborList(Atoms *atoms, double rCut, double driftfactor); friend void PyAsap_Dealloc(PyObject *self); public: /// Enable full neighbor lists by calling this just after the constructor void EnableFullNeighborLists(); /// Check if full lists are enabled bool HasFullNeighborLists() const {return fulllists;} /// Get wrapped positions of all the atoms const vector &GetWrappedPositions() const {return cells->GetWrappedPositions();} void GetWrappedPositions(vector &wp) const {cells->GetWrappedPositions(wp);} /// Get scaled positions of all the atoms const vector &GetScaledPositions() const {return cells->GetScaledPositions();} /// 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(); /// 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); /// 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. virtual 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. virtual void GetNeighbors(int n, vector &neighbors) const; /// GetFullNeighbors is as GetNeighbors, but return a full list 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 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 by interface. /// 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 {return rCut + 2*drift;} /// Remake the list for one or more atoms that have moved. /// /// Their neighbor's lists will also be remade, their identities /// will be reported in the set 'affected'. void RemakeLists(const set &modified, set &affected); /// Test the partial remaking of lists. NEVER CALL ON IN-USE NB LIST! /// /// This function is the Python interface to RemakeLists. It should /// only be called directly for testing purposes. Calling it on a /// neighbor list used by a potential will lead to INCORRECT /// energies and forces! int TestPartialUpdate(set modified, PyObject *pyatoms); /// 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); /// Return the atoms access object. Used by a few tool functions. virtual Atoms *GetAtoms() const {return atoms;} string GetName() const {return "NeighborList";} /// 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(); void CheckFullListConsistency(const string where, bool chkdst = true); void printlist(int n) const; double GetMaxStrainDisplacement(); 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 drift; ///< The maximally allowed drift of an atom. double drift2; ///< The square of the maximally allowed drift of an atom. int maxLength; ///< The lenght of the longest neighbor list. bool firsttime; ///< True during the very first update. bool fulllists; ///< True if full neighbor lists are supported. bool pbc[3]; ///< Boundary conditions at last update. Vec storedSuperCell[3]; ///< So full neighbor list can be accessed. Vec referenceSuperCell[3]; ///< For detecting shape changes. /// Cell locator used when constructing the neighbor list. NeighborCellLocator *cells; PyObject *cells_obj; /// Table of possible translation vectors vector translationTable; /// The actual neigbor list (half list) vector< vector< pair > > nbList; /// The complementary neighbor list if full lists are enabled. vector< vector< pair > > complNbList; }; } // end namespace #endif // NEIGHBORLIST2