QMCPACK
ParticleBConds2D.h
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source License.
3 // See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2016 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
8 // Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
9 //
10 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
11 //////////////////////////////////////////////////////////////////////////////////////
12 
13 
14 #ifndef QMCPLUSPLUS_PARTICLE_BCONDS_2D_H
15 #define QMCPLUSPLUS_PARTICLE_BCONDS_2D_H
16 
17 #include <config.h>
18 #include "Lattice/CrystalLattice.h"
19 
20 namespace qmcplusplus
21 {
22 /** specialization for a periodic 2D cell
23 */
24 template<class T>
26 {
27  T r00, r10, r01, r11;
28  T g00, g10, g01, g11;
29  T r2max;
30  std::vector<TinyVector<T, 2>> nextcells;
31 
33  : r00(lat.R(0)),
34  r10(lat.R(2)),
35  r01(lat.R(1)),
36  r11(lat.R(3)),
37  g00(lat.G(0)),
38  g10(lat.G(2)),
39  g01(lat.G(1)),
40  g11(lat.G(3)),
41  r2max(lat.CellRadiusSq)
42  {
43  nextcells.resize(8);
44  int ic = 0;
45  for (int i = -1; i <= 1; ++i)
46  for (int j = -1; j <= 1; ++j)
47  {
48  if (!(i || j))
49  continue; //exclude zero
50  nextcells[ic][0] = i * r00 + j * r10;
51  nextcells[ic][1] = i * r01 + j * r11;
52  ++ic;
53  }
54  }
55 
56  /** evaluate the minimum distance
57  * @param lat lattice
58  * @param a displacement vector [-0.5,0.5)x[-0.5,0.5)x[-0.5,0.5)
59  * @param r2max square of the maximum cutoff
60  * @return square of the minimum-image distance
61  *
62  * Search the ghost cells to match Wigner-Seitz cell
63  */
65  {
66  T d2 = a[0] * a[0] + a[1] * a[1];
67  if (d2 < r2max)
68  return d2;
69  else
70  {
71  T d2min = d2;
72  int ic = -1;
73  for (int i = 0; i < 8; ++i)
74  {
75  TinyVector<T, 2> c(a + nextcells[i]);
76  d2 = c[0] * c[0] + c[1] * c[1];
77  if (d2 < d2min)
78  {
79  d2min = d2;
80  ic = i;
81  }
82  }
83  if (ic >= 0)
84  a += nextcells[ic];
85  return d2min;
86  }
87  }
88 
89  /** apply BC to a displacement vector a and return the minimum-image distance
90  * @param lat lattice
91  * @param a displacement vector
92  * @return the minimum-image distance
93  */
94  inline T apply_bc(TinyVector<T, 2>& displ) const
95  {
96  //cart2unit
97  TinyVector<T, 2> ar(displ[0] * g00 + displ[1] * g10, displ[0] * g01 + displ[1] * g11);
98  //put them in the box
99  ar[0] -= round(ar[0]);
100  ar[1] -= round(ar[1]);
101  //unit2cart
102  displ[0] = ar[0] * r00 + ar[1] * r10;
103  displ[1] = ar[0] * r01 + ar[1] * r11;
104  //return |displ|^2 after checking the ghost cells
105  return get_min_distance(displ);
106  }
107 
108  inline void apply_bc(std::vector<TinyVector<T, 2>>& dr, std::vector<T>& r, std::vector<T>& rinv) const
109  {
110  const int n = dr.size();
111  for (int i = 0; i < n; ++i)
112  rinv[i] = apply_bc(dr[i]);
113  simd::sqrt(&rinv[0], &r[0], n);
114  simd::inv(&r[0], &rinv[0], n);
115  }
116 
117  inline void apply_bc(std::vector<TinyVector<T, 2>>& dr, std::vector<T>& r) const
118  {
119  for (int i = 0; i < dr.size(); ++i)
120  r[i] = apply_bc(dr[i]);
121  }
122 };
123 
124 /** specialization for a periodic 2D general cell with wigner-seitz==simulation cell
125  *
126  * Skip image cells.
127  */
128 template<class T>
129 struct DTD_BConds<T, 2, PPPS>
130 {
131  T r00, r10, r01, r11;
132  T g00, g10, g01, g11;
133  T r2max;
134  std::vector<TinyVector<T, 2>> nextcells;
135 
137  : r00(lat.R(0)),
138  r10(lat.R(2)),
139  r01(lat.R(1)),
140  r11(lat.R(3)),
141  g00(lat.G(0)),
142  g10(lat.G(2)),
143  g01(lat.G(1)),
144  g11(lat.G(3)),
145  r2max(lat.CellRadiusSq)
146  {}
147 
148  /** apply BC to a displacement vector a and return the minimum-image distance
149  * @param lat lattice
150  * @param a displacement vector
151  * @return the minimum-image distance
152  */
153  inline T apply_bc(TinyVector<T, 2>& displ) const
154  {
155  //cart2unit
156  TinyVector<T, 2> ar(displ[0] * g00 + displ[1] * g10, displ[0] * g01 + displ[1] * g11);
157  //put them in the box
158  ar[0] -= round(ar[0]);
159  ar[1] -= round(ar[1]);
160  //unit2cart
161  displ[0] = ar[0] * r00 + ar[1] * r10;
162  displ[1] = ar[0] * r01 + ar[1] * r11;
163  return displ[0] * displ[0] + displ[1] * displ[1];
164  }
165 
166  inline void apply_bc(std::vector<TinyVector<T, 2>>& dr, std::vector<T>& r, std::vector<T>& rinv) const
167  {
168  const int n = dr.size();
169  for (int i = 0; i < n; ++i)
170  rinv[i] = apply_bc(dr[i]);
171  simd::sqrt(&rinv[0], &r[0], n);
172  simd::inv(&r[0], &rinv[0], n);
173  }
174 
175  inline void apply_bc(std::vector<TinyVector<T, 2>>& dr, std::vector<T>& r) const
176  {
177  for (int i = 0; i < dr.size(); ++i)
178  r[i] = apply_bc(dr[i]);
179  }
180 };
181 
182 /** specialization for a periodic 2D orthorombic cell
183 */
184 template<class T>
185 struct DTD_BConds<T, 2, PPPO>
186 {
187  T Linv0, L0, Linv1, L1;
188 
189  inline DTD_BConds(const CrystalLattice<T, 2>& lat)
190  : Linv0(lat.OneOverLength[0]), L0(lat.Length[0]), Linv1(lat.OneOverLength[1]), L1(lat.Length[1])
191  {}
192 
193  /** evaluate |a| and apply boundary conditions on a
194  * @param lat lattice
195  * @param a Cartesian vector
196  * @return |a|^2
197  */
198  inline T apply_bc(TinyVector<T, 2>& displ) const
199  {
200  T x = displ[0] * Linv0;
201  displ[0] = L0 * (x - round(x));
202  T y = displ[1] * Linv1;
203  displ[1] = L1 * (y - round(y));
204  return displ[0] * displ[0] + displ[1] * displ[1];
205  }
206 
207  /** evaluate displacement data for a vector
208  */
209  inline void apply_bc(std::vector<TinyVector<T, 2>>& dr, std::vector<T>& r, std::vector<T>& rinv) const
210  {
211  const int n = r.size();
212  //use rinv as temporary rr
213  for (int i = 0; i < n; ++i)
214  rinv[i] = apply_bc(dr[i]);
215  simd::sqrt(&rinv[0], &r[0], n);
216  simd::inv(&r[0], &rinv[0], n);
217  }
218 
219  inline void apply_bc(std::vector<TinyVector<T, 2>>& dr, std::vector<T>& r) const
220  {
221  for (int i = 0; i < dr.size(); ++i)
222  r[i] = dot(dr[i], dr[i]);
223  }
224 };
225 
226 /** specialization for a wire in 2D
227 */
228 template<class T>
230 {
231  T Linv0, L0;
232 
233  inline DTD_BConds(const CrystalLattice<T, 2>& lat) : Linv0(lat.OneOverLength[0]), L0(lat.Length[0]) {}
234 
235  /** evaluate |a| and apply boundary conditions on a
236  * @param lat lattice
237  * @param a Cartesian vector
238  * @return |a|^2
239  */
240  inline T apply_bc(TinyVector<T, 2>& displ) const
241  {
242  T x = displ[0] * Linv0;
243  displ[0] = L0 * (x - round(x));
244  return displ[0] * displ[0] + displ[1] * displ[1];
245  }
246 
247  /** evaluate displacement data for a vector
248  */
249  inline void apply_bc(std::vector<TinyVector<T, 2>>& dr, std::vector<T>& r, std::vector<T>& rinv) const
250  {
251  const int n = r.size();
252  //use rinv as temporary rr
253  for (int i = 0; i < n; ++i)
254  rinv[i] = apply_bc(dr[i]);
255  simd::sqrt(&rinv[0], &r[0], n);
256  simd::inv(&r[0], &rinv[0], n);
257  }
258 
259  inline void apply_bc(std::vector<TinyVector<T, 2>>& dr, std::vector<T>& r) const
260  {
261  for (int i = 0; i < dr.size(); ++i)
262  r[i] = dot(dr[i], dr[i]);
263  }
264 };
265 
266 } // namespace qmcplusplus
267 #endif // OHMMS_PARTICLE_BCONDS_2D_H
a class that defines a supercell in D-dimensional Euclean space.
Fixed-size array.
Definition: OhmmsTinyMeta.h:30
DTD_BConds(const CrystalLattice< T, 2 > &lat)
T get_min_distance(TinyVector< T, 2 > &a) const
evaluate the minimum distance
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
void apply_bc(std::vector< TinyVector< T, 2 >> &dr, std::vector< T > &r, std::vector< T > &rinv) const
evaluate displacement data for a vector
void apply_bc(std::vector< TinyVector< T, 2 >> &dr, std::vector< T > &r) const
void apply_bc(std::vector< TinyVector< T, 2 >> &dr, std::vector< T > &r, std::vector< T > &rinv) const
evaluate displacement data for a vector
Declaration of CrystalLattice<T,D>
T apply_bc(TinyVector< T, D > &displ) const
apply BC on displ and return |displ|^2
std::vector< TinyVector< T, 2 > > nextcells
std::vector< TinyVector< T, 2 > > nextcells
T apply_bc(TinyVector< T, 2 > &displ) const
apply BC to a displacement vector a and return the minimum-image distance
void inv(const T *restrict in, T *restrict out, int n)
Definition: vmath.hpp:65
T apply_bc(TinyVector< T, 2 > &displ) const
apply BC to a displacement vector a and return the minimum-image distance
void apply_bc(std::vector< TinyVector< T, 2 >> &dr, std::vector< T > &r) const
T apply_bc(TinyVector< T, 2 > &displ) const
evaluate |a| and apply boundary conditions on a
DTD_BConds(const CrystalLattice< T, 2 > &lat)
Tensor< typename BinaryReturn< T1, T2, OpMultiply >::Type_t, D > dot(const AntiSymTensor< T1, D > &lhs, const AntiSymTensor< T2, D > &rhs)
void apply_bc(std::vector< TinyVector< T, 2 >> &dr, std::vector< T > &r) const
T apply_bc(TinyVector< T, 2 > &displ) const
evaluate |a| and apply boundary conditions on a
void apply_bc(std::vector< TinyVector< T, 2 >> &dr, std::vector< T > &r, std::vector< T > &rinv) const
DTD_BConds(const CrystalLattice< T, 2 > &lat)
void apply_bc(std::vector< TinyVector< T, 2 >> &dr, std::vector< T > &r) const
void sqrt(T *restrict inout, SIZET n)
Definition: vmath.hpp:52
DTD_BConds(const CrystalLattice< T, 2 > &lat)
void apply_bc(std::vector< TinyVector< T, 2 >> &dr, std::vector< T > &r, std::vector< T > &rinv) const