QMCPACK
ParticleBConds3D.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 // Ye Luo, yeluo@anl.gov, Argonne National Laboratory
10 //
11 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
12 //////////////////////////////////////////////////////////////////////////////////////
13 
14 
15 #ifndef QMCPLUSPLUS_PARTICLE_BCONDS_3D_H
16 #define QMCPLUSPLUS_PARTICLE_BCONDS_3D_H
17 
18 #include <config.h>
19 #include "Lattice/CrystalLattice.h"
20 
21 namespace qmcplusplus
22 {
23 /** specialization for a periodic 3D, orthorombic cell
24 */
25 template<class T>
26 struct DTD_BConds<T, 3, PPPO>
27 {
28  T Linv0, L0, Linv1, L1, Linv2, L2, r2max, dummy;
29 
30  inline DTD_BConds(const CrystalLattice<T, 3>& lat)
31  : Linv0(lat.OneOverLength[0]),
32  L0(lat.Length[0]),
33  Linv1(lat.OneOverLength[1]),
34  L1(lat.Length[1]),
35  Linv2(lat.OneOverLength[2]),
36  L2(lat.Length[2]),
37  r2max(lat.CellRadiusSq),
38  dummy(T())
39  {}
40 
41  /** apply BC on a displacement vector
42  * @param displ
43  */
44  inline T apply_bc(TinyVector<T, 3>& displ) const
45  {
46  T x = displ[0] * Linv0;
47  displ[0] = L0 * (x - round(x));
48  T y = displ[1] * Linv1;
49  displ[1] = L1 * (y - round(y));
50  T z = displ[2] * Linv2;
51  displ[2] = L2 * (z - round(z));
52  return displ[0] * displ[0] + displ[1] * displ[1] + displ[2] * displ[2];
53  }
54 
55  /** evaluate displacement data for a vector
56  */
57  inline void apply_bc(std::vector<TinyVector<T, 3>>& dr, std::vector<T>& r, std::vector<T>& rinv) const
58  {
59  const int n = r.size();
60  //use rinv as temporary rr
61  for (int i = 0; i < n; ++i)
62  rinv[i] = apply_bc(dr[i]);
63  simd::sqrt(&rinv[0], &r[0], n);
64  simd::inv(&r[0], &rinv[0], n);
65  }
66 
67  inline void apply_bc(std::vector<TinyVector<T, 3>>& dr, std::vector<T>& r) const
68  {
69  for (int i = 0; i < dr.size(); ++i)
70  r[i] = dot(dr[i], dr[i]);
71  }
72 
73  inline void evaluate_rsquared(TinyVector<T, 3>* restrict dr, T* restrict rr, int n)
74  {
75  for (int i = 0; i < n; ++i)
76  rr[i] = apply_bc(dr[i]);
77  }
78 };
79 
80 /** specialization for a periodic 3D general cell with wigner-seitz==simulation cell
81  *
82  * Skip image cells.
83  */
84 template<class T>
85 struct DTD_BConds<T, 3, PPPS>
86 {
87  T r00, r10, r20, r01, r11, r21, r02, r12, r22;
88  T g00, g10, g20, g01, g11, g21, g02, g12, g22;
90  : r00(lat.R(0)),
91  r10(lat.R(3)),
92  r20(lat.R(6)),
93  r01(lat.R(1)),
94  r11(lat.R(4)),
95  r21(lat.R(7)),
96  r02(lat.R(2)),
97  r12(lat.R(5)),
98  r22(lat.R(8)),
99  g00(lat.G(0)),
100  g10(lat.G(3)),
101  g20(lat.G(6)),
102  g01(lat.G(1)),
103  g11(lat.G(4)),
104  g21(lat.G(7)),
105  g02(lat.G(2)),
106  g12(lat.G(5)),
107  g22(lat.G(8))
108  {}
109 
110  /** apply BC to a displacement vector a and return the minimum-image distance
111  * @param lat lattice
112  * @param a displacement vector
113  * @return the minimum-image distance
114  */
115  inline T apply_bc(TinyVector<T, 3>& displ) const
116  {
117  //cart2unit
118  TinyVector<T, 3> ar(displ[0] * g00 + displ[1] * g10 + displ[2] * g20,
119  displ[0] * g01 + displ[1] * g11 + displ[2] * g21,
120  displ[0] * g02 + displ[1] * g12 + displ[2] * g22);
121  //put them in the box
122  ar[0] -= round(ar[0]);
123  ar[1] -= round(ar[1]);
124  ar[2] -= round(ar[2]);
125  //unit2cart
126  displ[0] = ar[0] * r00 + ar[1] * r10 + ar[2] * r20;
127  displ[1] = ar[0] * r01 + ar[1] * r11 + ar[2] * r21;
128  displ[2] = ar[0] * r02 + ar[1] * r12 + ar[2] * r22;
129  return displ[0] * displ[0] + displ[1] * displ[1] + displ[2] * displ[2];
130  }
131 
132  inline void apply_bc(std::vector<TinyVector<T, 3>>& dr, std::vector<T>& r, std::vector<T>& rinv) const
133  {
134  const int n = dr.size();
135  for (int i = 0; i < n; ++i)
136  rinv[i] = apply_bc(dr[i]);
137  simd::sqrt(&rinv[0], &r[0], n);
138  simd::inv(&r[0], &rinv[0], n);
139  }
140 
141  inline void apply_bc(std::vector<TinyVector<T, 3>>& dr, std::vector<T>& r) const
142  {
143  for (int i = 0; i < dr.size(); ++i)
144  r[i] = apply_bc(dr[i]);
145  }
146 
147  inline void evaluate_rsquared(TinyVector<T, 3>* restrict dr, T* restrict rr, int n)
148  {
149  for (int i = 0; i < n; ++i)
150  rr[i] = apply_bc(dr[i]);
151  }
152 };
153 
154 /** specialization for a periodic 3D general cell
155  *
156  * Wigner-Seitz cell radius > simulation cell radius
157  * Need to check image cells
158 */
159 template<class T>
160 struct DTD_BConds<T, 3, PPPG>
161 {
162  T g00, g10, g20, g01, g11, g21, g02, g12, g22;
164  std::vector<TinyVector<T, 3>> corners;
165 
167  {
168  rb[0] = lat.a(0);
169  rb[1] = lat.a(1);
170  rb[2] = lat.a(2);
171  find_reduced_basis(rb);
172  Tensor<T, 3> rbt;
173  for (int i = 0; i < 3; ++i)
174  for (int j = 0; j < 3; ++j)
175  rbt(i, j) = rb[i][j];
176  Tensor<T, 3> g = inverse(rbt);
177  T minusone = -1.0;
178  corners.resize(8);
179  corners[0] = 0.0;
180  corners[1] = minusone * (rb[0]);
181  corners[2] = minusone * (rb[1]);
182  corners[3] = minusone * (rb[2]);
183  corners[4] = minusone * (rb[0] + rb[1]);
184  corners[5] = minusone * (rb[0] + rb[2]);
185  corners[6] = minusone * (rb[1] + rb[2]);
186  corners[7] = minusone * (rb[0] + rb[1] + rb[2]);
187 
188  g00 = g(0);
189  g10 = g(3);
190  g20 = g(6);
191  g01 = g(1);
192  g11 = g(4);
193  g21 = g(7);
194  g02 = g(2);
195  g12 = g(5);
196  g22 = g(8);
197  }
198 
199  /** apply BC to a displacement vector a and return the minimum-image distance
200  * @param lat lattice
201  * @param a displacement vector
202  * @return the minimum-image distance
203  */
204  inline T apply_bc(TinyVector<T, 3>& displ) const
205  {
206  //cart2unit
207  TinyVector<T, 3> ar(displ[0] * g00 + displ[1] * g10 + displ[2] * g20,
208  displ[0] * g01 + displ[1] * g11 + displ[2] * g21,
209  displ[0] * g02 + displ[1] * g12 + displ[2] * g22);
210  ar[0] = -std::floor(ar[0]);
211  ar[1] = -std::floor(ar[1]);
212  ar[2] = -std::floor(ar[2]);
213  displ += ar[0] * rb[0] + ar[1] * rb[1] + ar[2] * rb[2];
214  T rmin2 = dot(displ, displ);
215  int imin = 0;
216  for (int i = 1; i < corners.size(); ++i)
217  {
218  TinyVector<T, 3> tv = displ + corners[i];
219  T r2 = dot(tv, tv);
220  if (r2 < rmin2)
221  {
222  rmin2 = r2;
223  imin = i;
224  }
225  }
226  if (imin > 0)
227  displ += corners[imin];
228  return rmin2;
229  }
230 
231  inline void apply_bc(std::vector<TinyVector<T, 3>>& dr, std::vector<T>& r, std::vector<T>& rinv) const
232  {
233  const int n = dr.size();
234  for (int i = 0; i < n; ++i)
235  rinv[i] = apply_bc(dr[i]);
236  simd::sqrt(&rinv[0], &r[0], n);
237  simd::inv(&r[0], &rinv[0], n);
238  }
239 
240  inline void apply_bc(std::vector<TinyVector<T, 3>>& dr, std::vector<T>& r) const
241  {
242  for (int i = 0; i < dr.size(); ++i)
243  r[i] = apply_bc(dr[i]);
244  }
245 
246  inline void evaluate_rsquared(TinyVector<T, 3>* restrict dr, T* restrict rr, int n)
247  {
248  for (int i = 0; i < n; ++i)
249  rr[i] = apply_bc(dr[i]);
250  }
251 };
252 
253 
254 /** specialization for a slab, general cell
255 */
256 template<class T>
257 struct DTD_BConds<T, 3, PPNG>
258 {
259  T g00, g10, g01, g11;
261  std::vector<TinyVector<T, 3>> corners;
262 
264  {
265  rb[0] = lat.a(0);
266  rb[1] = lat.a(1);
267  rb[2] = lat.a(2); //rb[2]=0.0;
268  g00 = lat.G(0);
269  g10 = lat.G(3);
270  g01 = lat.G(1);
271  g11 = lat.G(4);
272  T minusone = -1.0;
273  corners.resize(4);
274  corners[0] = 0.0;
275  corners[1] = minusone * (rb[0]);
276  corners[2] = minusone * (rb[1]);
277  corners[3] = minusone * (rb[0] + rb[1]);
278  }
279 
280  inline T apply_bc(TinyVector<T, 3>& displ) const
281  {
282  //cart2unit
283  TinyVector<T, 2> ar(displ[0] * g00 + displ[1] * g10, displ[0] * g01 + displ[1] * g11);
284  //put them in the box
285  ar[0] -= std::floor(ar[0]);
286  ar[1] -= std::floor(ar[1]);
287  displ += ar[0] * rb[0] + ar[1] * rb[1];
288  T rmin2 = dot(displ, displ);
289  int imin = 0;
290  for (int i = 1; i < corners.size(); ++i)
291  {
292  TinyVector<T, 3> tv = displ + corners[i];
293  T r2 = dot(tv, tv);
294  if (r2 < rmin2)
295  {
296  rmin2 = r2;
297  imin = i;
298  }
299  }
300  if (imin > 0)
301  displ += corners[imin];
302  return rmin2;
303  }
304 
305  inline void apply_bc(std::vector<TinyVector<T, 3>>& dr, std::vector<T>& r, std::vector<T>& rinv) const
306  {
307  const int n = dr.size();
308  for (int i = 0; i < n; ++i)
309  rinv[i] = apply_bc(dr[i]);
310  simd::sqrt(&rinv[0], &r[0], n);
311  simd::inv(&r[0], &rinv[0], n);
312  }
313 
314  inline void apply_bc(std::vector<TinyVector<T, 3>>& dr, std::vector<T>& r) const
315  {
316  for (int i = 0; i < dr.size(); ++i)
317  r[i] = apply_bc(dr[i]);
318  }
319 
320  inline void evaluate_rsquared(TinyVector<T, 3>* restrict dr, T* restrict rr, int n)
321  {
322  for (int i = 0; i < n; ++i)
323  rr[i] = apply_bc(dr[i]);
324  }
325 };
326 
327 /** specialization for a slab, orthorombic cell
328 */
329 template<class T>
330 struct DTD_BConds<T, 3, PPNO>
331 {
332  T Linv0, L0, Linv1, L1;
333 
334  inline DTD_BConds(const CrystalLattice<T, 3>& lat)
335  : Linv0(lat.OneOverLength[0]), L0(lat.Length[0]), Linv1(lat.OneOverLength[1]), L1(lat.Length[1])
336  {}
337 
338  /** evaluate |a| and apply boundary conditions on a
339  */
340  inline T apply_bc(TinyVector<T, 3>& displ) const
341  {
342  T x = displ[0] * Linv0;
343  displ[0] = L0 * (x - round(x));
344  T y = displ[1] * Linv1;
345  displ[1] = L1 * (y - round(y));
346  return displ[0] * displ[0] + displ[1] * displ[1] + displ[2] * displ[2];
347  }
348 
349  /** evaluate displacement data for a vector
350  */
351  inline void apply_bc(std::vector<TinyVector<T, 3>>& dr, std::vector<T>& r, std::vector<T>& rinv) const
352  {
353  const int n = r.size();
354  //use rinv as temporary rr
355  for (int i = 0; i < n; ++i)
356  rinv[i] = apply_bc(dr[i]);
357  simd::sqrt(&rinv[0], &r[0], n);
358  simd::inv(&r[0], &rinv[0], n);
359  }
360 
361  inline void apply_bc(std::vector<TinyVector<T, 3>>& dr, std::vector<T>& r) const
362  {
363  for (int i = 0; i < dr.size(); ++i)
364  r[i] = dot(dr[i], dr[i]);
365  }
366 
367  inline void evaluate_rsquared(TinyVector<T, 3>* restrict dr, T* restrict rr, int n)
368  {
369  for (int i = 0; i < n; ++i)
370  rr[i] = apply_bc(dr[i]);
371  }
372 };
373 
374 template<class T>
375 struct DTD_BConds<T, 3, PPNS>
376 {
377  T r00, r10, r01, r11;
378  T g00, g10, g01, g11;
380  : r00(lat.R(0)),
381  r10(lat.R(3)),
382  r01(lat.R(1)),
383  r11(lat.R(4)),
384  g00(lat.G(0)),
385  g10(lat.G(3)),
386  g01(lat.G(1)),
387  g11(lat.G(4))
388  {}
389 
390  /** apply BC to a displacement vector a and return the minimum-image distance
391  * @param lat lattice
392  * @param a displacement vector
393  * @return the minimum-image distance
394  */
395  inline T apply_bc(TinyVector<T, 3>& displ) const
396  {
397  //cart2unit
398  TinyVector<T, 2> ar(displ[0] * g00 + displ[1] * g10, displ[0] * g01 + displ[1] * g11);
399  //put them in the box
400  ar[0] -= round(ar[0]);
401  ar[1] -= round(ar[1]);
402  //unit2cart
403  displ[0] = ar[0] * r00 + ar[1] * r10;
404  displ[1] = ar[0] * r01 + ar[1] * r11;
405  return displ[0] * displ[0] + displ[1] * displ[1] + displ[2] * displ[2];
406  }
407 
408  inline void apply_bc(std::vector<TinyVector<T, 3>>& dr, std::vector<T>& r, std::vector<T>& rinv) const
409  {
410  const int n = dr.size();
411  for (int i = 0; i < n; ++i)
412  rinv[i] = apply_bc(dr[i]);
413  simd::sqrt(&rinv[0], &r[0], n);
414  simd::inv(&r[0], &rinv[0], n);
415  }
416 
417  inline void apply_bc(std::vector<TinyVector<T, 3>>& dr, std::vector<T>& r) const
418  {
419  for (int i = 0; i < dr.size(); ++i)
420  r[i] = apply_bc(dr[i]);
421  }
422 
423  inline void evaluate_rsquared(TinyVector<T, 3>* restrict dr, T* restrict rr, int n)
424  {
425  for (int i = 0; i < n; ++i)
426  rr[i] = apply_bc(dr[i]);
427  }
428 };
429 
430 
431 /** specialization for a wire
432 */
433 template<class T>
435 {
436  T Linv0, L0;
437 
438  inline DTD_BConds(const CrystalLattice<T, 3>& lat) : Linv0(lat.OneOverLength[0]), L0(lat.Length[0]) {}
439 
440  /** evaluate |a| and apply boundary conditions on a
441  * @param lat lattice
442  * @param a Cartesian vector
443  * @return |a|^2
444  */
445  inline T apply_bc(TinyVector<T, 3>& displ) const
446  {
447  T x = displ[0] * Linv0;
448  displ[0] = L0 * (x - round(x));
449  return displ[0] * displ[0] + displ[1] * displ[1] + displ[2] * displ[2];
450  }
451 
452  /** evaluate displacement data for a vector
453  */
454  inline void apply_bc(std::vector<TinyVector<T, 3>>& dr, std::vector<T>& r, std::vector<T>& rinv) const
455  {
456  const int n = r.size();
457  //use rinv as temporary rr
458  for (int i = 0; i < n; ++i)
459  rinv[i] = apply_bc(dr[i]);
460  simd::sqrt(&rinv[0], &r[0], n);
461  simd::inv(&r[0], &rinv[0], n);
462  }
463 
464  inline void apply_bc(std::vector<TinyVector<T, 3>>& dr, std::vector<T>& r) const
465  {
466  for (int i = 0; i < dr.size(); ++i)
467  r[i] = dot(dr[i], dr[i]);
468  }
469 
470  inline void evaluate_rsquared(TinyVector<T, 3>* restrict dr, T* restrict rr, int n)
471  {
472  for (int i = 0; i < n; ++i)
473  rr[i] = apply_bc(dr[i]);
474  }
475 };
476 
477 /** specialization for a periodic 3D general cell
478  *
479  * Slow method and not used unless one needs to check if faster methods fail
480  */
481 template<class T>
482 struct DTD_BConds<T, 3, PPPX>
483 {
484  T r00, r10, r20, r01, r11, r21, r02, r12, r22;
485  T g00, g10, g20, g01, g11, g21, g02, g12, g22;
486  T r2max;
487  std::vector<TinyVector<T, 3>> nextcells;
488 
490  : r00(lat.R(0)),
491  r10(lat.R(3)),
492  r20(lat.R(6)),
493  r01(lat.R(1)),
494  r11(lat.R(4)),
495  r21(lat.R(7)),
496  r02(lat.R(2)),
497  r12(lat.R(5)),
498  r22(lat.R(8)),
499  g00(lat.G(0)),
500  g10(lat.G(3)),
501  g20(lat.G(6)),
502  g01(lat.G(1)),
503  g11(lat.G(4)),
504  g21(lat.G(7)),
505  g02(lat.G(2)),
506  g12(lat.G(5)),
507  g22(lat.G(8)),
508  r2max(lat.CellRadiusSq)
509  {
510  nextcells.resize(26);
511  int ic = 0;
512  for (int i = -1; i <= 1; ++i)
513  for (int j = -1; j <= 1; ++j)
514  for (int k = -1; k <= 1; ++k)
515  {
516  if (!(i || j || k))
517  continue; //exclude zero
518  nextcells[ic][0] = i * r00 + j * r10 + k * r20;
519  nextcells[ic][1] = i * r01 + j * r11 + k * r21;
520  nextcells[ic][2] = i * r02 + j * r12 + k * r22;
521  ++ic;
522  }
523  }
524 
525  /** evaluate the minimum distance
526  * @param lat lattice
527  * @param a displacement vector [-0.5,0.5)x[-0.5,0.5)x[-0.5,0.5)
528  * @param r2max square of the maximum cutoff
529  * @return square of the minimum-image distance
530  *
531  * Search the ghost cells to match Wigner-Seitz cell
532  */
534  {
535  T d2 = a[0] * a[0] + a[1] * a[1] + a[2] * a[2];
536  if (d2 < r2max)
537  return d2;
538  else
539  {
540  T d2min = d2;
541  int ic = -1;
542  for (int i = 0; i < nextcells.size(); ++i)
543  {
544  TinyVector<T, 3> c(a + nextcells[i]);
545  d2 = c[0] * c[0] + c[1] * c[1] + c[2] * c[2];
546  if (d2 < d2min)
547  {
548  d2min = d2;
549  ic = i;
550  }
551  }
552  if (ic >= 0)
553  a += nextcells[ic];
554  return d2min;
555  }
556  }
557 
558  /** apply BC to a displacement vector a and return the minimum-image distance
559  * @param lat lattice
560  * @param a displacement vector
561  * @return the minimum-image distance
562  */
563  inline T apply_bc(TinyVector<T, 3>& displ) const
564  {
565  //cart2unit
566  TinyVector<T, 3> ar(displ[0] * g00 + displ[1] * g10 + displ[2] * g20,
567  displ[0] * g01 + displ[1] * g11 + displ[2] * g21,
568  displ[0] * g02 + displ[1] * g12 + displ[2] * g22);
569  //put them in the box
570  ar[0] -= round(ar[0]);
571  ar[1] -= round(ar[1]);
572  ar[2] -= round(ar[2]);
573  //unit2cart
574  displ[0] = ar[0] * r00 + ar[1] * r10 + ar[2] * r20;
575  displ[1] = ar[0] * r01 + ar[1] * r11 + ar[2] * r21;
576  displ[2] = ar[0] * r02 + ar[1] * r12 + ar[2] * r22;
577  //return |displ|^2 after checking the ghost cells
578  return get_min_distance(displ);
579  }
580 
581  /** out = prod (in ,lattice)
582  * @param lattice 3x3 tensor to for conversion, either CrystalLattice::R or CrystalLattice::G
583  * @param in start address of input vectors, in[n][3]
584  * @param out start address of output vectors, out[n][3]
585  * @param n number of 3d vectors
586  */
587  inline void convert2Cart(const T* restrict in, T* restrict out, int n) const
588  {
589  for (int i = 0, i3 = 0; i < n; ++i, i3 += 3)
590  {
591  out[i3] = in[i3] * r00 + in[i3 + 1] * r10 + in[i3 + 2] * r20;
592  out[i3 + 1] = in[i3] * r01 + in[i3 + 1] * r11 + in[i3 + 2] * r21;
593  out[i3 + 2] = in[i3] * r02 + in[i3 + 1] * r12 + in[i3 + 2] * r22;
594  }
595  }
596 
597  inline void convert2Unit(const T* restrict in, T* restrict out, int n) const
598  {
599  for (int i = 0, i3 = 0; i < n; ++i, i3 += 3)
600  {
601  out[i3] = in[i3] * g00 + in[i3 + 1] * g10 + in[i3 + 2] * g20;
602  out[i3 + 1] = in[i3] * g01 + in[i3 + 1] * g11 + in[i3 + 2] * g21;
603  out[i3 + 2] = in[i3] * g02 + in[i3 + 1] * g12 + in[i3 + 2] * g22;
604  }
605  }
606 
607  inline void apply_bc(std::vector<TinyVector<T, 3>>& dr, std::vector<T>& r, std::vector<T>& rinv) const
608  {
609  const int n = dr.size();
610  for (int i = 0; i < n; ++i)
611  rinv[i] = apply_bc(dr[i]);
612  //using inline function but is not better
613  //T drnew[n*3];
614  //convert2Unit(&dr[0][0],drnew,n);
615  //for(int i=0; i<n*3;++i) drnew[i]-= round(drnew[i]);
616  //convert2Cart(drnew,&dr[0][0],n);
617  //for(int i=0; i<n; ++i) rinv[i]=get_min_distance(dr[i]);
618  simd::sqrt(&rinv[0], &r[0], n);
619  simd::inv(&r[0], &rinv[0], n);
620  }
621 
622  inline void apply_bc(std::vector<TinyVector<T, 3>>& dr, std::vector<T>& r) const
623  {
624  for (int i = 0; i < dr.size(); ++i)
625  r[i] = apply_bc(dr[i]);
626  }
627 
628  inline void evaluate_rsquared(TinyVector<T, 3>* restrict dr, T* restrict rr, int n)
629  {
630  for (int i = 0; i < n; ++i)
631  rr[i] = apply_bc(dr[i]);
632  }
633 };
634 
635 /** specialization for a slab, general cell
636 */
637 template<class T>
638 struct DTD_BConds<T, 3, PPNX>
639 {
640  T r00, r10, r01, r11;
641  T g00, g10, g01, g11;
642  T r2max;
643  std::vector<TinyVector<T, 3>> nextcells;
644 
646  : r00(lat.R(0)),
647  r10(lat.R(3)),
648  r01(lat.R(1)),
649  r11(lat.R(4)),
650  g00(lat.G(0)),
651  g10(lat.G(3)),
652  g01(lat.G(1)),
653  g11(lat.G(4)),
654  r2max(lat.CellRadiusSq)
655  {
656  nextcells.resize(8);
657  int ic = 0;
658  for (int i = -1; i <= 1; ++i)
659  for (int j = -1; j <= 1; ++j)
660  {
661  if (!(i || j))
662  continue; //exclude zero
663  nextcells[ic][0] = i * r00 + j * r10;
664  nextcells[ic][1] = i * r01 + j * r11;
665  nextcells[ic][2] = 0;
666  ++ic;
667  }
668  }
669 
670  /** evaluate the minimum distance
671  * @param lat lattice
672  * @param a displacement vector \f$[-0.5,0.5)\times [-0.5,0.5)\times [-\infty,\infty)\f$
673  * @param r2max square of the maximum cutoff
674  * @return square of the minimum-image distance
675  *
676  * Search the ghost cells to match Wigner-Seitz cell
677  */
679  {
680  T d2 = a[0] * a[0] + a[1] * a[1] + a[2] * a[2];
681  if (d2 < r2max)
682  return d2;
683  else
684  {
685  T d2min = d2;
686  int ic = -1;
687  for (int i = 0; i < 8; ++i)
688  {
689  TinyVector<T, 3> c(a + nextcells[i]);
690  d2 = c[0] * c[0] + c[1] * c[1] + c[2] * c[2];
691  if (d2 < d2min)
692  {
693  d2min = d2;
694  ic = i;
695  }
696  }
697  if (ic >= 0)
698  a += nextcells[ic];
699  return d2min;
700  }
701  }
702 
703  /** apply BC to a displacement vector a and return the minimum-image distance
704  * @param lat lattice
705  * @param a displacement vector
706  * @return the minimum-image distance
707  */
708  inline T apply_bc(TinyVector<T, 3>& displ) const
709  {
710  //cart2unit
711  TinyVector<T, 2> ar(displ[0] * g00 + displ[1] * g10, displ[0] * g01 + displ[1] * g11);
712  //put them in the box
713  ar[0] -= round(ar[0]);
714  ar[1] -= round(ar[1]);
715  //unit2cart
716  displ[0] = ar[0] * r00 + ar[1] * r10;
717  displ[1] = ar[0] * r01 + ar[1] * r11;
718  //return |displ|^2 after checking the ghost cells
719  return get_min_distance(displ);
720  }
721 
722  inline void apply_bc(std::vector<TinyVector<T, 3>>& dr, std::vector<T>& r, std::vector<T>& rinv) const
723  {
724  const int n = dr.size();
725  for (int i = 0; i < n; ++i)
726  rinv[i] = apply_bc(dr[i]);
727  simd::sqrt(&rinv[0], &r[0], n);
728  simd::inv(&r[0], &rinv[0], n);
729  }
730 
731  inline void apply_bc(std::vector<TinyVector<T, 3>>& dr, std::vector<T>& r) const
732  {
733  for (int i = 0; i < dr.size(); ++i)
734  r[i] = apply_bc(dr[i]);
735  }
736 
737  inline void evaluate_rsquared(TinyVector<T, 3>* restrict dr, T* restrict rr, int n)
738  {
739  for (int i = 0; i < n; ++i)
740  rr[i] = apply_bc(dr[i]);
741  }
742 };
743 
744 
745 } // namespace qmcplusplus
746 
747 #endif // OHMMS_PARTICLE_BCONDS_3D_H
T apply_bc(TinyVector< T, 3 > &displ) const
apply BC to a displacement vector a and return the minimum-image distance
a class that defines a supercell in D-dimensional Euclean space.
void evaluate_rsquared(TinyVector< T, 3 > *restrict dr, T *restrict rr, int n)
void evaluate_rsquared(TinyVector< T, 3 > *restrict dr, T *restrict rr, int n)
Fixed-size array.
Definition: OhmmsTinyMeta.h:30
std::vector< TinyVector< T, 3 > > corners
void apply_bc(std::vector< TinyVector< T, 3 >> &dr, std::vector< T > &r, std::vector< T > &rinv) const
evaluate displacement data for a vector
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
void convert2Cart(const T *restrict in, T *restrict out, int n) const
out = prod (in ,lattice)
DTD_BConds(const CrystalLattice< T, 3 > &lat)
T apply_bc(TinyVector< T, 3 > &displ) const
apply BC to a displacement vector a and return the minimum-image distance
void apply_bc(std::vector< TinyVector< T, 3 >> &dr, std::vector< T > &r, std::vector< T > &rinv) const
T apply_bc(TinyVector< T, 3 > &displ) const
apply BC to a displacement vector a and return the minimum-image distance
void evaluate_rsquared(TinyVector< T, 3 > *restrict dr, T *restrict rr, int n)
T apply_bc(TinyVector< T, 3 > &displ) const
apply BC to a displacement vector a and return the minimum-image distance
DTD_BConds(const CrystalLattice< T, 3 > &lat)
void convert2Unit(const T *restrict in, T *restrict out, int n) const
void apply_bc(std::vector< TinyVector< T, 3 >> &dr, std::vector< T > &r, std::vector< T > &rinv) const
evaluate displacement data for a vector
T apply_bc(TinyVector< T, 3 > &displ) const
apply BC to a displacement vector a and return the minimum-image distance
Tensor_t G
Reciprocal unit vectors. G(j,i) i=vector and j=x,y,z.
T apply_bc(TinyVector< T, 3 > &displ) const
evaluate |a| and apply boundary conditions on a
Declaration of CrystalLattice<T,D>
TinyVector< TinyVector< T, 3 >, 3 > rb
DTD_BConds(const CrystalLattice< T, 3 > &lat)
void evaluate_rsquared(TinyVector< T, 3 > *restrict dr, T *restrict rr, int n)
DTD_BConds(const CrystalLattice< T, 3 > &lat)
T apply_bc(TinyVector< T, D > &displ) const
apply BC on displ and return |displ|^2
void apply_bc(std::vector< TinyVector< T, 3 >> &dr, std::vector< T > &r) const
void apply_bc(std::vector< TinyVector< T, 3 >> &dr, std::vector< T > &r, std::vector< T > &rinv) const
void apply_bc(std::vector< TinyVector< T, 3 >> &dr, std::vector< T > &r) const
T apply_bc(TinyVector< T, 3 > &displ) const
apply BC on a displacement vector
DTD_BConds(const CrystalLattice< T, 3 > &lat)
void evaluate_rsquared(TinyVector< T, 3 > *restrict dr, T *restrict rr, int n)
void apply_bc(std::vector< TinyVector< T, 3 >> &dr, std::vector< T > &r, std::vector< T > &rinv) const
void apply_bc(std::vector< TinyVector< T, 3 >> &dr, std::vector< T > &r) const
T apply_bc(TinyVector< T, 3 > &displ) const
Tensor<T,D> class for D by D tensor.
Definition: OhmmsTinyMeta.h:32
void evaluate_rsquared(TinyVector< T, 3 > *restrict dr, T *restrict rr, int n)
DTD_BConds(const CrystalLattice< T, 3 > &lat)
DTD_BConds(const CrystalLattice< T, 3 > &lat)
void apply_bc(std::vector< TinyVector< T, 3 >> &dr, std::vector< T > &r, std::vector< T > &rinv) const
evaluate displacement data for a vector
std::vector< TinyVector< T, 3 > > corners
SingleParticlePos a(int i) const
Provide interfaces familiar to fotran users.
void apply_bc(std::vector< TinyVector< T, 3 >> &dr, std::vector< T > &r) const
std::vector< TinyVector< T, 3 > > nextcells
void inv(const T *restrict in, T *restrict out, int n)
Definition: vmath.hpp:65
void evaluate_rsquared(TinyVector< T, 3 > *restrict dr, T *restrict rr, int n)
void apply_bc(std::vector< TinyVector< T, 3 >> &dr, std::vector< T > &r) const
void find_reduced_basis(TinyVector< TinyVector< T, 3 >, 3 > &rb)
void apply_bc(std::vector< TinyVector< T, 3 >> &dr, std::vector< T > &r, std::vector< T > &rinv) const
void apply_bc(std::vector< TinyVector< T, 3 >> &dr, std::vector< T > &r) const
void evaluate_rsquared(TinyVector< T, 3 > *restrict dr, T *restrict rr, int n)
DTD_BConds(const CrystalLattice< T, 3 > &lat)
T get_min_distance(TinyVector< T, 3 > &a) const
evaluate the minimum distance
Tensor< T, D > inverse(const Tensor< T, D > &a)
Definition: TensorOps.h:879
std::vector< TinyVector< T, 3 > > nextcells
Tensor< typename BinaryReturn< T1, T2, OpMultiply >::Type_t, D > dot(const AntiSymTensor< T1, D > &lhs, const AntiSymTensor< T2, D > &rhs)
DTD_BConds(const CrystalLattice< T, 3 > &lat)
void apply_bc(std::vector< TinyVector< T, 3 >> &dr, std::vector< T > &r, std::vector< T > &rinv) const
void apply_bc(std::vector< TinyVector< T, 3 >> &dr, std::vector< T > &r) const
void apply_bc(std::vector< TinyVector< T, 3 >> &dr, std::vector< T > &r) const
void evaluate_rsquared(TinyVector< T, 3 > *restrict dr, T *restrict rr, int n)
void apply_bc(std::vector< TinyVector< T, 3 >> &dr, std::vector< T > &r, std::vector< T > &rinv) const
void sqrt(T *restrict inout, SIZET n)
Definition: vmath.hpp:52
TinyVector< TinyVector< T, 3 >, 3 > rb
T get_min_distance(TinyVector< T, 3 > &a) const
evaluate the minimum distance
MakeReturn< UnaryNode< FnFloor, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t floor(const Vector< T1, C1 > &l)
void apply_bc(std::vector< TinyVector< T, 3 >> &dr, std::vector< T > &r) const
T apply_bc(TinyVector< T, 3 > &displ) const
evaluate |a| and apply boundary conditions on a