Avogadro  1.1.0
/home/kitware/dashboards/avogadro/libavogadro/src/neighborlist.h
00001 /*********************************************************************
00002   NeighborList - NeighborList class
00003 
00004   Copyright (C) 2009 by Tim Vandermeersch
00005 
00006   This file is part of the Avogadro molecular editor project.
00007   For more information, see <http://avogadro.openmolecules.net/>
00008 
00009   Avogadro is free software; you can redistribute it and/or modify
00010   it under the terms of the GNU General Public License as published by
00011   the Free Software Foundation; either version 2 of the License, or
00012   (at your option) any later version.
00013 
00014   Avogadro is distributed in the hope that it will be useful,
00015   but WITHOUT ANY WARRANTY; without even the implied warranty of
00016   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017   GNU General Public License for more details.
00018 
00019   You should have received a copy of the GNU General Public License
00020   along with this program; if not, write to the Free Software
00021   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00022   02110-1301, USA.
00023 ***********************************************************************/
00024 
00025 #ifndef NEIGHBORLIST_H
00026 #define NEIGHBORLIST_H
00027 
00028 #include <avogadro/molecule.h>
00029 
00030 #include <Eigen/Core>
00031 
00032 namespace Avogadro
00033 {
00050   class Atom;
00051 
00052   class A_EXPORT NeighborList
00053   {
00054     private:
00055       typedef std::vector<Atom*>::iterator atom_iter;
00056 
00057     public:
00064       NeighborList(Molecule *mol, double rcut, bool periodic = false, int boxSize = 1);
00072       NeighborList(const QList<Atom*> &atoms, double rcut, bool periodic = false, int boxSize = 1);
00073 
00080       void update();
00091       QList<Atom*> nbrs(Atom *atom, bool uniqueOnly = true);
00099       QList<Atom*> nbrs(const Eigen::Vector3f *pos);
00106       inline double r2(unsigned int index) const
00107       {
00108         return m_r2.at(index);
00109       }
00110 
00111     private:
00112       inline unsigned int ghostIndex(int i, int j, int k) const
00113       {
00114         i += m_boxSize + 1;
00115         j += m_boxSize + 1;
00116         k += m_boxSize + 1;
00117         return i + j * m_ghostX + k * m_ghostXY;
00118       }
00119 
00120       inline unsigned int ghostIndex(const Eigen::Vector3i &index) const
00121       {
00122         return ghostIndex(index.x(), index.y(), index.z());
00123       }
00124 
00125       inline unsigned int cellIndex(int i, int j, int k) const
00126       {
00127         return i + j * m_dim.x() + k * m_xyDim;
00128       }
00129 
00130       inline unsigned int cellIndex(const Eigen::Vector3i &index) const
00131       {
00132         return index.x() + index.y() * m_dim.x() + index.z() * m_xyDim;
00133       }
00134 
00135 
00136       inline unsigned int cellIndex(const Eigen::Vector3d &pos) const
00137       {
00138         return cellIndex( int(floor( (pos.x() - m_min.x()) / m_edgeLength )),
00139                           int(floor( (pos.y() - m_min.y()) / m_edgeLength )),
00140                           int(floor( (pos.z() - m_min.z()) / m_edgeLength )) );
00141       }
00142 
00143       inline Eigen::Vector3i cellIndexes(const Eigen::Vector3d *pos) const
00144       {
00145         Eigen::Vector3i index;
00146         index.x() = int(floor( (pos->x() - m_min.x()) / m_edgeLength ));
00147         index.y() = int(floor( (pos->y() - m_min.y()) / m_edgeLength ));
00148         index.z() = int(floor( (pos->z() - m_min.z()) / m_edgeLength ));
00149         return index;
00150       }
00151 
00157       inline bool IsOneTwo(unsigned int i, unsigned int j) const
00158       {
00159         std::vector<unsigned int>::const_iterator iter;
00160         for (iter = m_oneTwo.at(i).begin(); iter != m_oneTwo.at(i).end(); ++iter)
00161           if (*iter == j)
00162             return true;
00163 
00164         return false;
00165       }
00166 
00172       inline bool IsOneThree(unsigned int i, unsigned int j) const
00173       {
00174         std::vector<unsigned int>::const_iterator iter;
00175         for (iter = m_oneThree.at(i).begin(); iter != m_oneThree.at(i).end(); ++iter)
00176           if (*iter == j)
00177             return true;
00178 
00179         return false;
00180       }
00181 
00185       void initOneTwo();
00186       void initCells();
00187       void updateCells();
00188       void initOffsetMap();
00189       void initGhostMap(bool periodic = false);
00190       bool insideShpere(const Eigen::Vector3i &index);
00191 
00192       QList<Atom*>                        m_atoms;
00193       double                              m_rcut, m_rcut2;
00194       double                              m_edgeLength;
00195       int                                 m_boxSize;
00196       int                                 m_updateCounter;
00197 
00198 
00199       Eigen::Vector3d                     m_min, m_max;
00200       Eigen::Vector3i                     m_dim;
00201       int                                 m_xyDim;
00202       std::vector<std::vector<Atom*> >    m_cells;
00203 
00204       std::vector<Eigen::Vector3i>        m_offsetMap;
00205       std::vector<Eigen::Vector3i>        m_ghostMap;
00206       int                                 m_ghostX;
00207       int                                 m_ghostXY;
00208 
00209       std::vector<double>                 m_r2;
00210 
00211       std::vector<std::vector<unsigned int> > m_oneTwo;
00212       std::vector<std::vector<unsigned int> > m_oneThree;
00213   };
00214 
00215 } // end namespace OpenBabel
00216 
00218 
00219 #endif