Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2011-2023 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 "View.h" 28 : #include "View2D.h" 29 : #include <vector> 30 : #include <cstddef> 31 : #include <limits> 32 : 33 : namespace PLMD { 34 : 35 : template <std::size_t N=3> 36 : using MemoryView=View<double,N>; 37 : 38 : template < std::size_t N=helpers::dynamic_extent, std::size_t STRIDE=3> 39 : using mdMemoryView = View2D<double,N,STRIDE>; 40 : 41 : using VectorView = mdMemoryView<helpers::dynamic_extent, 3>; 42 : 43 : /* 44 : Tool to deal with periodic boundary conditions. 45 : 46 : This class is useful to apply periodic boundary conditions on interatomic 47 : distances. It stores privately information about reduced lattice vectors 48 : */ 49 : class Pbc { 50 : /// Type of box 51 : enum {unset,orthorombic,generic} type; 52 : /// Maximum number of shifts to be tried for a given octant. 53 : /// This is an exact bound: buildShifts only keeps shifts whose nonzero 54 : /// components have the sign opposite to the octant, and with one or two 55 : /// nonzero components (out of three) there are 3+3=6 such shifts. 56 : static constexpr unsigned maxshiftsize=6; 57 : /// Box 58 : Tensor box; 59 : /// Inverse box 60 : Tensor invBox; 61 : /// Reduced box. 62 : /// This is a set of lattice vectors generating the same lattice 63 : /// but "minimally skewed". Useful to optimize image search. 64 : Tensor reduced; 65 : /// Inverse of the reduced box 66 : Tensor invReduced; 67 : /// List of shifts that should be attempted. 68 : /// Depending on the sign of the scaled coordinates representing 69 : /// a distance vector, a different set of shifts must be tried. 70 : /// Fixed-size arrays (rather than a container with a pointer to its data) 71 : /// are used so that a bitwise copy of the object, as done by OpenACC, 72 : /// is also valid on the device. 73 : Vector shifts[2][2][2][maxshiftsize]; 74 : /// Number of valid entries in each list of shifts 75 : unsigned nShiftsPerOctant[2][2][2]; 76 : /// Alternative representation for orthorhombic cells. 77 : /// Not really used, but could be used to optimize search in 78 : /// orthorhombic cells. 79 : Vector diag,hdiag,mdiag; 80 : /// Build list of shifts. 81 : /// This is expensive, and must be called only when box is 82 : /// reset. It allows building a minimal set of shifts 83 : /// depending on the sign of the scaled coordinates representing 84 : /// a distance vector. 85 : void buildShifts(); 86 : public: 87 : ///Helper function for moving the class to an openacc device 88 : void toACCDevice()const ; 89 : ///Helper function for cleaning the memory of the class from an openacc device 90 : void removeFromACCDevice() const; 91 : /// Constructor 92 : Pbc(); 93 : /// Compute modulo of (v2-v1), using or not pbc depending on bool pbc. 94 : double distance( const bool pbc, const Vector& v1, const Vector& v2 ) const; 95 : /// Computes v2-v1, using minimal image convention 96 : /// if specified, also returns the number of attempted shifts 97 : #pragma acc routine seq 98 : Vector distance(const Vector&, const Vector&)const; 99 : #pragma acc routine seq 100 : Vector3f distance(const Vector3f&, const Vector3f&)const; 101 : /// Computes v2-v1, using minimal image convention 102 : /// if specified, also returns the number of attempted shifts 103 : Vector distance(const Vector&, const Vector&,int*nshifts)const; 104 : /// Apply PBC to a set of positions or distance vectors 105 : #pragma acc routine seq 106 : void apply(VectorView dlist, unsigned max_index=0) const; 107 : #pragma acc routine seq 108 : void apply(std::vector<Vector>&dlist, unsigned max_index=0) const; 109 : /// Set the lattice vectors. 110 : /// b[i][j] is the j-th component of the i-th vector 111 : void setBox(const Tensor&b); 112 : /// Returns the box 113 : #pragma acc routine seq 114 : const Tensor& getBox()const; 115 : /// Returns the inverse matrix of box. 116 : /// Thus: pbc.getInvBox() == inverse(pbc.getBox()). 117 : #pragma acc routine seq 118 : const Tensor& getInvBox()const; 119 : /// Transform a vector in real space to a vector in scaled coordinates. 120 : /// Thus:pbc.realToScaled(v) == matmul(transpose(inverse(pbc.getBox(),v))); 121 : #pragma acc routine seq 122 : Vector realToScaled(const Vector&)const; 123 : #pragma acc routine seq 124 : Vector3f realToScaled(const Vector3f&)const; 125 : /// Transform a vector in scaled coordinates to a vector in real space. 126 : /// Thus:pbc.scaledToRead(v) == matmul(transpose(pbc.getBox()),v); 127 : #pragma acc routine seq 128 : Vector scaledToReal(const Vector&)const; 129 : #pragma acc routine seq 130 : Vector3f scaledToReal(const Vector3f&)const; 131 : /// Returns true if the box vectors are orthogonal 132 : #pragma acc routine seq 133 : bool isOrthorombic()const; 134 : /// Full search (for testing). 135 : /// Perform a full search on vector 136 : void fullSearch(Vector&)const; 137 : /// Returns true if box is set and non zero 138 : bool isSet()const; 139 : }; 140 : 141 : inline 142 : bool Pbc::isSet()const { 143 37574 : return type!=unset; 144 : } 145 : 146 : } 147 : 148 : #endif