1 // -*- C++ -*-
2 //
3 // NeighborLocator.h: Abstract base class for all neighbor lists and
4 // similar.
5 //
6 // Copyright (C) 2001-2011 Jakob Schiotz and Center for Individual
7 // Nanoparticle Functionality, Department of Physics, Technical
8 // University of Denmark.  Email: schiotz@fysik.dtu.dk
9 //
10 // This file is part of Asap version 3.
11 // Asap is released under the GNU Lesser Public License (LGPL) version 3.
12 // However, the parts of Asap distributed within the OpenKIM project
13 // (including this file) are also released under the Common Development
14 // and Distribution License (CDDL) version 1.0.
15 //
16 // This program is free software: you can redistribute it and/or
17 // modify it under the terms of the GNU Lesser General Public License
18 // version 3 as published by the Free Software Foundation.  Permission
19 // to use other versions of the GNU Lesser General Public License may
20 // granted by Jakob Schiotz or the head of department of the
21 // Department of Physics, Technical University of Denmark, as
22 // described in section 14 of the GNU General Public License.
23 //
24 // This program is distributed in the hope that it will be useful,
25 // but WITHOUT ANY WARRANTY; without even the implied warranty of
26 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27 // GNU General Public License for more details.
28 //
29 // You should have received a copy of the GNU General Public License
30 // and the GNU Lesser Public License along with this program.  If not,
31 // see <http://www.gnu.org/licenses/>.
32 
33 
34 #ifndef NEIGHBORLOCATOR_H
35 #define NEIGHBORLOCATOR_H
36 
37 #include "AsapPython.h"
38 #include "AsapObject.h"
39 #include "Templates.h"
40 #include "Exception.h"
41 #include "Atoms.h"
42 #include <set>
43 #include <vector>
44 using std::set;
45 using std::vector;
46 
47 namespace ASAPSPACE {
48 
49 class Vec;
50 
51 class NeighborLocator;  // Defined later in this file.
52 
53 /// The Python object corresponding to a NeighborLocator object.
54 typedef struct {
55   PyObject_HEAD
56   NeighborLocator *cobj;
57   PyObject *weakrefs;
58   bool fulllist;
59 } PyAsap_NeighborLocatorObject;
60 
61 bool PyAsap_NeighborLocatorCheck(PyObject *obj);  // Implemented in NeighborLocatorInterface.cpp
62 
63 /// Mostly abstract base class for neighbor locators and neighbor lists.
64 
65 /// A little common functionality is included in this otherwise
66 /// abstract base class, in particular a number of flags best handled
67 /// with inline member functions, and unlikely to need redefinition.
68 
69 class NeighborLocator : public AsapObject
70 {
71 protected:
NeighborLocator()72   NeighborLocator() {invalid=true; verbose=0;}
73 
74 public:
75   // Destructor should be protected, but friend template functions do
76   // not work with GNU C++.
~NeighborLocator()77   virtual ~NeighborLocator() {};
78 
79   /// Check if the neighbor list can still be reused, update if not.
80   ///
81   /// If an implementation does not support multithreading, it must
82   /// throw an exception if called with non-default arguments.
83   virtual bool CheckAndUpdateNeighborList() = 0;
84 
85   /// Check if the neighbor list can still be reused, update if not.
86   ///
87   /// This version is used when called from Python
88   virtual bool CheckAndUpdateNeighborList(PyObject *atoms) = 0;
89 
90   /// Check the neighbor list.
91   ///
92   /// Check if the neighbor list can still be reused, return true if
93   /// it should be updated.
94   virtual bool CheckNeighborList() = 0;
95 
96   /// Update neighbor list
97   virtual void UpdateNeighborList() = 0;
98 
99   /// Get wrapped positions of all the atoms
100   virtual const vector<Vec> &GetWrappedPositions() const = 0;
101 
102   virtual void GetWrappedPositions(vector<Vec> &wp) const = 0;
103 
104   /// Get scaled positions of all the atoms
105   virtual const vector<Vec> &GetScaledPositions() const = 0;
106 
107   /// Get info about the neighbors of atom n.  The most important method :-)
108   ///
109   /// Input values: n is the number of the atom.  r (optional) is a
110   /// cutoff, must be less than rCut in the constructor (not
111   /// checked!).
112   ///
113   /// In-out values: size contains the maximum space in the arrays.
114   /// It is decremented by the number of neighbors placed in the
115   /// arrays.  It is an error to call GetNeighbors with too small a
116   /// value of size.
117   ///
118   /// Out values: neighbors[] contains the numbers of the atoms,
119   /// diffs[] contains the \em relative positions of the atoms,
120   /// diffs2[] contains the norms of the diffs vectors.
121   ///
122   /// Return value: The number of neighbors.
123   virtual int GetNeighbors(int n, int *neighbors, Vec *diffs, double *diffs2,
124 			   int& size, double r = -1.0) const = 0;
125 
126   /// Get the neighbors of atom n (half neighbor list).
127   ///
128   /// This version of GetNeighbors only returns the numbers of the neighbors.
129   /// It is intended for the Python interface.
130   virtual void GetNeighbors(int n, vector<int> &neighbors) const = 0;
131 
132   /// Return the guaranteed maximal length of a single atom's NB list.
133 
134   /// Call this before using GetNeighbors() to make sure the arrays
135   /// are big enough.  The value may change when the neighbor list is
136   /// updated.
137   virtual int MaxNeighborListLength() const = 0;
138 
139   /// Return the cutoff distance of this neighbor locator.
140   virtual double GetCutoffRadius() const = 0;
141 
142   /// Return the cutoff distance including twice the drift.
143   virtual double GetCutoffRadiusWithDrift() const = 0;
144 
145   /// Get the number of atoms in the corresponding list of atoms.
146   virtual int GetNumberOfAtoms() const = 0;  // Used by the Python interface
147 
148   /// Invalidate a neighbor list.
Invalidate()149   void Invalidate() {invalid = true;}
150 
151   /// Return true if neighbor list has been invalidated.
IsInvalid()152   bool IsInvalid() {return invalid;}
153 
154   /// Return the atoms access object.  Used by a few tool functions.
155   virtual Atoms *GetAtoms() const = 0;
156 
157   // The following methods are only implemented in a "Full" neighbor locator.
158 
159   virtual int GetFullNeighbors(int n, int *neighbors, Vec *diffs,
160 			       double *diffs2, int& size,
161 			       double r = -1.0) const
162   {throw
163       AsapError("Internal error: Calling half neighbor locator as a full one.");}
164 
GetFullNeighbors(int n,vector<int> & neighbors)165   virtual void GetFullNeighbors(int n, vector<int> &neighbors) const
166   {throw
167       AsapError("Internal error: Calling half neighbor locator as a full one.");}
168 
169   /// Print internal info about an atom
170   virtual void print_info(int n) = 0;
171 
172   /// Print memory usage
173   virtual long PrintMemory() const = 0;
174 
175 protected:
176   bool invalid;   ///< True if a list has been invalidated.
177 
178 public:
179   int verbose;    ///< Verbosity.  Can be set by the potential.
180 };
181 
182 } // end namespace
183 
184 #endif // NEIGHBORLOCATOR_H
185