1 /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2    Copyright (c) 2011-2021 The plumed team
3    (see the PEOPLE file at the root of the distribution for a list of names)
4 
5    See http://www.plumed.org for more information.
6 
7    This file is part of plumed, version 2.
8 
9    plumed is free software: you can redistribute it and/or modify
10    it under the terms of the GNU Lesser General Public License as published by
11    the Free Software Foundation, either version 3 of the License, or
12    (at your option) any later version.
13 
14    plumed is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU Lesser General Public License for more details.
18 
19    You should have received a copy of the GNU Lesser General Public License
20    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
21 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
22 #ifndef __PLUMED_tools_Pbc_h
23 #define __PLUMED_tools_Pbc_h
24 
25 #include "Vector.h"
26 #include "Tensor.h"
27 #include <vector>
28 #include <cstddef>
29 
30 namespace PLMD {
31 
32 /*
33 Tool to deal with periodic boundary conditions.
34 
35 This class is useful to apply periodic boundary conditions on interatomic
36 distances. It stores privately information about reduced lattice vectors
37 */
38 class Pbc {
39 /// Type of box
40   enum {unset,orthorombic,generic} type;
41 /// Box
42   Tensor box;
43 /// Inverse box
44   Tensor invBox;
45 /// Reduced box.
46 /// This is a set of lattice vectors generating the same lattice
47 /// but "minimally skewed". Useful to optimize image search.
48   Tensor reduced;
49 /// Inverse of the reduced box
50   Tensor invReduced;
51 /// List of shifts that should be attempted.
52 /// Depending on the sign of the scaled coordinates representing
53 /// a distance vector, a different set of shifts must be tried.
54   std::vector<Vector> shifts[2][2][2];
55 /// Alternative representation for orthorombic cells.
56 /// Not really used, but could be used to optimize search in
57 /// orthorombic cells.
58   Vector diag,hdiag,mdiag;
59 /// Build list of shifts.
60 /// This is expensive, and must be called only when box is
61 /// reset. It allows building a minimal set of shifts
62 /// depending on the sign of the scaled coordinates representing
63 /// a distance vector.
64   void buildShifts(std::vector<Vector> shifts[2][2][2])const;
65 public:
66 /// Constructor
67   Pbc();
68 /// Compute modulo of (v2-v1), using or not pbc depending on bool pbc.
69   double distance( const bool pbc, const Vector& v1, const Vector& v2 ) const;
70 /// Computes v2-v1, using minimal image convention
71   Vector distance(const Vector& v1,const Vector& v2)const;
72 /// version of distance which also returns the number
73 /// of attempted shifts
74   Vector distance(const Vector&,const Vector&,int*nshifts)const;
75 /// Apply PBC to a set of positions or distance vectors
76   void apply(std::vector<Vector>&dlist, unsigned max_index=0) const;
77 /// Set the lattice vectors.
78 /// b[i][j] is the j-th component of the i-th vector
79   void setBox(const Tensor&b);
80 /// Returns the box
81   const Tensor& getBox()const;
82 /// Returns the inverse matrix of box.
83 /// Thus: pbc.getInvBox() == inverse(pbc.getBox()).
84   const Tensor& getInvBox()const;
85 /// Transform a vector in real space to a vector in scaled coordinates.
86 /// Thus:pbc.realToScaled(v) == matmul(transpose(inverse(pbc.getBox(),v)));
87   Vector realToScaled(const Vector&)const;
88 /// Transform a vector in scaled coordinates to a vector in real space.
89 /// Thus:pbc.scaledToRead(v) == matmul(transpose(pbc.getBox()),v);
90   Vector scaledToReal(const Vector&)const;
91 /// Returns true if the box vectors are orthogonal
92   bool isOrthorombic()const;
93 /// Full search (for testing).
94 /// Perform a full search on vector
95   void fullSearch(Vector&)const;
96 /// Returns true if box is set and non zero
97   bool isSet()const;
98 };
99 
100 inline
distance(const Vector & v1,const Vector & v2)101 Vector Pbc::distance(const Vector& v1,const Vector& v2)const {
102   return distance(v1,v2,NULL);
103 }
104 
105 inline
isSet()106 bool Pbc::isSet()const {
107   return type!=unset;
108 }
109 
110 }
111 
112 #endif
113