From d399cbc6ce83ad7576251a130bba3ce8ddb7c17e Mon Sep 17 00:00:00 2001
From: Giovanni Bussi <giovanni.bussi@gmail.com>
Date: Sun, 28 Apr 2013 11:41:49 +0200
Subject: [PATCH] Added some developer documentation for Pbc.

---
 src/tools/Pbc.cpp | 25 +++++++++++++++++++----
 src/tools/Pbc.h   | 51 +++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 70 insertions(+), 6 deletions(-)

diff --git a/src/tools/Pbc.cpp b/src/tools/Pbc.cpp
index e2fc52bf6..15e1ba401 100644
--- a/src/tools/Pbc.cpp
+++ b/src/tools/Pbc.cpp
@@ -38,23 +38,40 @@ Pbc::Pbc():
 
 void Pbc::buildShifts(std::vector<Vector> shifts[2][2][2])const{
   const double small=1e-28;
+
+// clear all shifts
   for(int i=0;i<2;i++) for(int j=0;j<2;j++) for(int k=0;k<2;k++) shifts[i][j][k].clear();
+
+// enumerate all possible shifts
+// since box is reduced, only 27 shifts have to be attempted
   for(int l=-1;l<=1;l++) for(int m=-1;m<=1;m++) for(int n=-1;n<=1;n++){
+
+// int/double shift vectors
     int ishift[3]={l,m,n};
     Vector dshift(l,m,n);
-    unsigned count=0;
+
 // count how many components are != 0
+    unsigned count=0;
     for(int s=0;s<3;s++) if(ishift[s]!=0) count++;
+
 // skips trivial (0,0,0) and cases with three shifts
+// only 18 shifts survive past this point
     if(count==0 || count==3) continue;
-// check if that WS face is perpendicular to the axis
+
+// check if that Wigner-Seitz face is perpendicular to the axis.
+// this allows to eliminate shifts in symmetric cells.
+// e.g., if one lactice vector is orthogonal to the plane spanned
+// by the other two vectors, that shift should never be tried
     Vector cosdir=matmul(reduced,transpose(reduced),dshift);
     double dp=dotProduct(dshift,cosdir);
     double ref=modulo2(dshift)*modulo2(cosdir);
     if(std::fabs(ref-dp*dp)<small) continue;
 
+// here we start pruning depending on the sign of the scaled coordinate
     for(int i=0;i<2;i++) for(int j=0;j<2;j++) for(int k=0;k<2;k++){
+
       int block[3]={2*i-1,2*j-1,2*k-1};
+
 // skip cases where shift would bring too far from origin
       bool skip=false;
       for(int s=0;s<3;s++) if(ishift[s]*block[s]>0) skip=true;
@@ -66,6 +83,8 @@ void Pbc::buildShifts(std::vector<Vector> shifts[2][2][2])const{
         if(((1-ishift[s]*ishift[s])*block[s])*cosdir[s]<-small) skip=false;
       }
       if(skip)continue;
+
+// if we arrive to this point, shift is eligible and is added to the list
       shifts[i][j][k].push_back(matmul(transpose(reduced),dshift));
     }
   }
@@ -83,8 +102,6 @@ void Pbc::fullSearch(Vector&d)const{
    Vector best(d);
    double lbest=d.modulo2();
    for(int i=-smax;i<=smax;i++) for(int j=-smax;j<=smax;j++) for(int k=-smax;k<=smax;k++){
-//     int x=i*i+j*j+k*k;
-//     if(x==0 || x==3) continue;
      Vector trial=d+i*a0+j*a1+k*a2;
      double ltrial=trial.modulo2();
      if(ltrial<lbest){
diff --git a/src/tools/Pbc.h b/src/tools/Pbc.h
index 1aa9dde9e..804feae5b 100644
--- a/src/tools/Pbc.h
+++ b/src/tools/Pbc.h
@@ -29,29 +29,76 @@
 
 namespace PLMD{
 
+/*
+Tool to deal with periodic boundary conditions.
+
+This class is useful to apply periodic boundary conditions on interatomic
+distances. It stores privately information about reduced lattice vectors
+*/
 class Pbc{
+/// Type of box
   enum {unset,orthorombic,generic} type;
+/// Box
   Tensor box;
+/// Inverse box
   Tensor invBox;
+/// Reduced box.
+/// This is a set of lattice vectors generating the same lattice
+/// but "minimally skewed". Useful to optimize image search.
   Tensor reduced;
+/// Inverse of the reduced box
   Tensor invReduced;
+/// List of shifts that should be attempted.
+/// Depending on the sign of the scaled coordinates representing
+/// a distance vector, a different set of shifts must be tried.
   std::vector<Vector> shifts[2][2][2];
+/// Alternative representation for orthorombic cells.
+/// Not really used, but could be used to optimize search in
+/// orthorombic cells.
   Vector diag,hdiag,mdiag;
+/// Build list of shifts.
+/// This is expensive, and must be called only when box is
+/// reset. It allows building a minimal set of shifts
+/// depending on the sign of the scaled coordinates representing
+/// a distance vector.
   void buildShifts(std::vector<Vector> shifts[2][2][2])const;
+/// Full search (for testing)
   void fullSearch(Vector&)const;
+/// internal version of distance, also returns the number
+/// of attempted shifts (used in Pbc::test()).
+  Vector distance(const Vector&,const Vector&,int*nshifts)const;
 public:
+/// Perform some check. Useful for debugging.
   static void test();
+/// Constructor
   Pbc();
+/// Compute modulo of (v2-v1), using or not pbc depending on bool pbc.
   double distance( const bool pbc, const Vector& v1, const Vector& v2 ) const;
-  Vector distance(const Vector&,const Vector&,int*nshifts=NULL)const;
-  void setBox(const Tensor&);
+/// Computes v2-v1, using minimal image convention
+  Vector distance(const Vector& v1,const Vector& v2)const;
+/// Set the lattice vectors.
+/// b[i][j] is the j-th component of the i-th vector
+  void setBox(const Tensor&b);
+/// Returns the box
   const Tensor& getBox()const;
+/// Returns the inverse matrix of box.
+/// Thus: pbc.getInvBox() == inverse(pbc.getBox()).
   const Tensor& getInvBox()const;
+/// Transform a vector in real space to a vector in scaled coordinates.
+/// Thus:pbc.realToScaled(v) == matmul(transpose(inverse(pbc.getBox(),v)));
   Vector realToScaled(const Vector&)const;
+/// Transform a vector in scaled coordinates to a vector in real space.
+/// Thus:pbc.scaledToRead(v) == matmul(transpose(pbc.getBox()),v);
   Vector scaledToReal(const Vector&)const;
+/// Returns true if the box vectors are orthogonal
   bool isOrthorombic()const;
 };
 
+inline
+Vector Pbc::distance(const Vector& v1,const Vector& v2)const{
+  return distance(v1,v2,NULL);
+}
+
 }
 
 #endif
-- 
GitLab