QMCPACK
FastParticleOperators.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: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
8 // Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
9 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
10 //
11 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
12 //////////////////////////////////////////////////////////////////////////////////////
13 
14 
15 /** @file FastParticleOperators.h
16  * @brief template functions to support conversion and handling of boundary conditions.
17  */
18 #ifndef OHMMS_FAST_PARTICLE_OPERATORS_H
19 #define OHMMS_FAST_PARTICLE_OPERATORS_H
20 
21 #include "CPU/SIMD/vmath.hpp"
22 
23 namespace qmcplusplus
24 {
25 /** Dummy template class to be specialized
26  *
27  * - T1 the datatype to be transformed
28  * - T2 the transformation matrix
29  */
30 template<class T1, class T2, unsigned D>
32 {};
33 
34 /** Specialized ConvertPosUnit for ParticleAttrib<T,3>, Tensor<T,3>
35  */
36 template<class T>
38 {
41 
42  inline static void apply(const Array_t& pin, const Transformer_t& X, Array_t& pout, int first, int last)
43  {
44  T x00 = X[0], x01 = X[1], x02 = X[2], x10 = X[3], x11 = X[4], x12 = X[5], x20 = X[6], x21 = X[7], x22 = X[8];
45 #pragma ivdep
46  for (int i = first; i < last; i++)
47  {
48  pout[i][0] = pin[i][0] * x00 + pin[i][1] * x10 + pin[i][2] * x20;
49  pout[i][1] = pin[i][0] * x01 + pin[i][1] * x11 + pin[i][2] * x21;
50  pout[i][2] = pin[i][0] * x02 + pin[i][1] * x12 + pin[i][2] * x22;
51  }
52  }
53 
54  inline static void apply(const Transformer_t& X, const Array_t& pin, Array_t& pout, int first, int last)
55  {
56  T x00 = X[0], x01 = X[1], x02 = X[2], x10 = X[3], x11 = X[4], x12 = X[5], x20 = X[6], x21 = X[7], x22 = X[8];
57 #pragma ivdep
58  for (int i = first; i < last; i++)
59  {
60  pout[i][0] = pin[i][0] * x00 + pin[i][1] * x01 + pin[i][2] * x02;
61  pout[i][1] = pin[i][0] * x10 + pin[i][1] * x11 + pin[i][2] * x12;
62  pout[i][2] = pin[i][0] * x20 + pin[i][1] * x21 + pin[i][2] * x22;
63  }
64  }
65 
66  inline static void apply(Array_t& pinout, const Transformer_t& X, int first, int last)
67  {
68  T x00 = X[0], x01 = X[1], x02 = X[2], x10 = X[3], x11 = X[4], x12 = X[5], x20 = X[6], x21 = X[7], x22 = X[8];
69 #pragma ivdep
70  for (int i = first; i < last; i++)
71  {
72  T _x(pinout[i][0]), _y(pinout[i][1]), _z(pinout[i][2]);
73  pinout[i][0] = _x * x00 + _y * x10 + _z * x20;
74  pinout[i][1] = _x * x01 + _y * x11 + _z * x21;
75  pinout[i][2] = _x * x02 + _y * x12 + _z * x22;
76  }
77  }
78 
79  inline static void apply(const Transformer_t& X, Array_t& pinout, int first, int last)
80  {
81  T x00 = X[0], x01 = X[1], x02 = X[2], x10 = X[3], x11 = X[4], x12 = X[5], x20 = X[6], x21 = X[7], x22 = X[8];
82 #pragma ivdep
83  for (int i = first; i < last; i++)
84  {
85  T _x(pinout[i][0]), _y(pinout[i][1]), _z(pinout[i][2]);
86  pinout[i][0] = _x * x00 + _y * x01 + _z * x02;
87  pinout[i][1] = _x * x10 + _y * x11 + _z * x12;
88  pinout[i][2] = _x * x20 + _y * x21 + _z * x22;
89  }
90  }
91 };
92 
93 
94 /** Specialized ConvertPosUnit for ParticleAttrib<T,2>, Tensor<T,2>
95  */
96 template<class T>
98 {
101 
102  inline static void apply(const Array_t& pin, const Transformer_t& X, Array_t& pout, int first, int last)
103  {
104  T x00 = X[0], x01 = X[1], x10 = X[2], x11 = X[3];
105 #pragma ivdep
106  for (int i = first; i < last; i++)
107  {
108  pout[i][0] = pin[i][0] * x00 + pin[i][1] * x10;
109  pout[i][1] = pin[i][0] * x01 + pin[i][1] * x11;
110  }
111  }
112 
113  inline static void apply(const Transformer_t& X, const Array_t& pin, Array_t& pout, int first, int last)
114  {
115  T x00 = X[0], x01 = X[1], x10 = X[2], x11 = X[3];
116 #pragma ivdep
117  for (int i = first; i < last; i++)
118  {
119  pout[i][0] = pin[i][0] * x00 + pin[i][1] * x01;
120  pout[i][1] = pin[i][0] * x10 + pin[i][1] * x11;
121  }
122  }
123 
124  inline static void apply(Array_t& pinout, const Transformer_t& X, int first, int last)
125  {
126  T x00 = X[0], x01 = X[1], x10 = X[2], x11 = X[3];
127 #pragma ivdep
128  for (int i = first; i < last; i++)
129  {
130  T _x(pinout[i][0]), _y(pinout[i][1]);
131  pinout[i][0] = _x * x00 + _y * x10;
132  pinout[i][1] = _x * x01 + _y * x11;
133  }
134  }
135 
136  inline static void apply(const Transformer_t& X, Array_t& pinout, int first, int last)
137  {
138  T x00 = X[0], x01 = X[1], x10 = X[2], x11 = X[3];
139 #pragma ivdep
140  for (int i = first; i < last; i++)
141  {
142  T _x(pinout[i][0]), _y(pinout[i][1]);
143  pinout[i][0] = _x * x00 + _y * x01;
144  pinout[i][1] = _x * x10 + _y * x11;
145  }
146  }
147 };
148 
149 #define SUPERCELL_BOUNDARY_LIMITS(T) \
150  const T epsilon = -std::numeric_limits<T>::epsilon(); \
151  const T plus_one = 1.0
152 
153 
154 #define THREE_DIM_BOUNDARY_BLOCK(X, Y, Z, EPS, PLUSONE) \
155  if (X < EPS) \
156  X += PLUSONE; \
157  else if (X >= PLUSONE) \
158  X -= PLUSONE; \
159  if (Y < EPS) \
160  Y += PLUSONE; \
161  else if (Y >= PLUSONE) \
162  Y -= PLUSONE; \
163  if (Z < EPS) \
164  Z += PLUSONE; \
165  else if (Z >= PLUSONE) \
166  Z -= PLUSONE
167 
168 #define TWO_DIM_BOUNDARY_BLOCK(X, Y, EPS, PLUSONE) \
169  if (X < EPS) \
170  X += PLUSONE; \
171  else if (X >= PLUSONE) \
172  X -= PLUSONE; \
173  if (Y < EPS) \
174  Y += PLUSONE; \
175  else if (Y >= PLUSONE) \
176  Y -= PLUSONE
177 
178 
179 /** Dummy template class to apply boundary conditions */
180 template<class T1, class T2, unsigned D>
182 {};
183 
184 template<class T>
185 struct ApplyBConds<ParticleAttrib<TinyVector<T, 3>>, Tensor<T, 3>, 3>
186 {
188  using Component_t = typename Array_t::Type_t;
190 
191  inline static void Cart2Cart(const Array_t& pin,
192  const Transformer_t& G,
193  const Transformer_t& R,
194  Array_t& pout,
195  int first,
196  int last)
197  {
199  T g00 = G[0], g01 = G[1], g02 = G[2], g10 = G[3], g11 = G[4], g12 = G[5], g20 = G[6], g21 = G[7], g22 = G[8];
200  T r00 = R[0], r01 = R[1], r02 = R[2], r10 = R[3], r11 = R[4], r12 = R[5], r20 = R[6], r21 = R[7], r22 = R[8];
201 #pragma ivdep
202  for (int i = first; i < last; i++)
203  {
204  T x(pin[i][0] * g00 + pin[i][1] * g10 + pin[i][2] * g20);
205  T y(pin[i][0] * g01 + pin[i][1] * g11 + pin[i][2] * g21);
206  T z(pin[i][0] * g02 + pin[i][1] * g12 + pin[i][2] * g22);
207  THREE_DIM_BOUNDARY_BLOCK(x, y, z, epsilon, plus_one);
208  pout[i][0] = x * r00 + y * r10 + z * r20;
209  pout[i][1] = x * r01 + y * r11 + z * r21;
210  pout[i][2] = x * r02 + y * r12 + z * r22;
211  }
212  }
213 
214  inline static void Cart2Unit(const Array_t& pin, const Transformer_t& G, Array_t& pout, int first, int last)
215  {
217  T g00 = G[0], g01 = G[1], g02 = G[2], g10 = G[3], g11 = G[4], g12 = G[5], g20 = G[6], g21 = G[7], g22 = G[8];
218 #pragma ivdep
219  for (int i = first; i < last; i++)
220  {
221  T x(pin[i][0] * g00 + pin[i][1] * g10 + pin[i][2] * g20);
222  T y(pin[i][0] * g01 + pin[i][1] * g11 + pin[i][2] * g21);
223  T z(pin[i][0] * g02 + pin[i][1] * g12 + pin[i][2] * g22);
224  THREE_DIM_BOUNDARY_BLOCK(x, y, z, epsilon, plus_one);
225  pout[i][0] = x;
226  pout[i][1] = y;
227  pout[i][2] = z;
228  }
229  }
230 
231  inline static void Unit2Cart(const Array_t& pin, const Transformer_t& R, Array_t& pout, int first, int last)
232  {
234  T r00 = R[0], r01 = R[1], r02 = R[2], r10 = R[3], r11 = R[4], r12 = R[5], r20 = R[6], r21 = R[7], r22 = R[8];
235 #pragma ivdep
236  for (int i = first; i < last; i++)
237  {
238  T x(pin[i][0]), y(pin[i][1]), z(pin[i][2]);
239  THREE_DIM_BOUNDARY_BLOCK(x, y, z, epsilon, plus_one);
240  pout[i][0] = x * r00 + y * r10 + z * r20;
241  pout[i][1] = x * r01 + y * r11 + z * r21;
242  pout[i][2] = x * r02 + y * r12 + z * r22;
243  }
244  }
245 
246  inline static void Unit2Unit(const Array_t& pin, Array_t& pout, int first, int last)
247  {
249 #pragma ivdep
250  for (int i = first; i < last; i++)
251  {
252  T x(pin[i][0]), y(pin[i][1]), z(pin[i][2]);
253  THREE_DIM_BOUNDARY_BLOCK(x, y, z, epsilon, plus_one);
254  pout[i][0] = x;
255  pout[i][1] = y;
256  pout[i][2] = z;
257  }
258  }
259 
260  inline static void Unit2Unit(Array_t& pinout, int first, int last)
261  {
263 #pragma ivdep
264  for (int i = first; i < last; i++)
265  {
266  T x(pinout[i][0]), y(pinout[i][1]), z(pinout[i][2]);
267  THREE_DIM_BOUNDARY_BLOCK(x, y, z, epsilon, plus_one);
268  pinout[i][0] = x;
269  pinout[i][1] = y;
270  pinout[i][2] = z;
271  }
272  }
273 
274  inline static void Cart2Cart(Array_t& pinout, const Transformer_t& G, const Transformer_t& R, int first, int last)
275  {
277  T g00 = G[0], g01 = G[1], g02 = G[2], g10 = G[3], g11 = G[4], g12 = G[5], g20 = G[6], g21 = G[7], g22 = G[8];
278  T r00 = R[0], r01 = R[1], r02 = R[2], r10 = R[3], r11 = R[4], r12 = R[5], r20 = R[6], r21 = R[7], r22 = R[8];
279 #pragma ivdep
280  for (int i = first; i < last; i++)
281  {
282  T x(pinout[i][0] * g00 + pinout[i][1] * g10 + pinout[i][2] * g20);
283  T y(pinout[i][0] * g01 + pinout[i][1] * g11 + pinout[i][2] * g21);
284  T z(pinout[i][0] * g02 + pinout[i][1] * g12 + pinout[i][2] * g22);
285  THREE_DIM_BOUNDARY_BLOCK(x, y, z, epsilon, plus_one);
286  pinout[i][0] = x * r00 + y * r10 + z * r20;
287  pinout[i][1] = x * r01 + y * r11 + z * r21;
288  pinout[i][2] = x * r02 + y * r12 + z * r22;
289  }
290  }
291 
292  static inline Component_t Unit2Unit(const Component_t& pos)
293  {
295  T x(pos[0]), y(pos[1]), z(pos[2]);
296  THREE_DIM_BOUNDARY_BLOCK(x, y, z, epsilon, plus_one);
297  return TinyVector<T, 3>(x, y, z);
298  }
299 
300  static inline Component_t Cart2Unit(const Component_t& pos, const Transformer_t& G)
301  {
303  T x(pos[0] * G[0] + pos[1] * G[3] + pos[2] * G[6]), y(pos[0] * G[1] + pos[1] * G[4] + pos[2] * G[7]),
304  z(pos[0] * G[2] + pos[1] * G[5] + pos[2] * G[8]);
305  THREE_DIM_BOUNDARY_BLOCK(x, y, z, epsilon, plus_one);
306  return Component_t(x, y, z);
307  }
308 
309  static inline Component_t Unit2Cart(const Component_t& pos, const Transformer_t& R)
310  {
312  T x(pos[0]), y(pos[1]), z(pos[2]);
313  THREE_DIM_BOUNDARY_BLOCK(x, y, z, epsilon, plus_one);
314  return Component_t(x * R[0] + y * R[3] + z * R[6], x * R[1] + y * R[4] + z * R[7], x * R[2] + y * R[5] + z * R[8]);
315  }
316 
317  static inline Component_t Cart2Cart(const Component_t& pos, const Transformer_t& G, const Transformer_t& R)
318  {
320  T x(pos[0] * G[0] + pos[1] * G[3] + pos[2] * G[6]), y(pos[0] * G[1] + pos[1] * G[4] + pos[2] * G[7]),
321  z(pos[0] * G[2] + pos[1] * G[5] + pos[2] * G[8]);
322  THREE_DIM_BOUNDARY_BLOCK(x, y, z, epsilon, plus_one);
323  return Component_t(x * R[0] + y * R[3] + z * R[6], x * R[1] + y * R[4] + z * R[7], x * R[2] + y * R[5] + z * R[8]);
324  }
325 };
326 
327 /** inout[i]=inout[i]-floor(inout[i])
328  *
329  * See CPU/SIMD/vmath.h and should be specialized for vector libraries, e.g., INTEL vml, IBM massv
330  */
331 template<typename T, unsigned D>
333 {
334  simd::remainder(&(inout[0][0]), inout.size() * D);
335 }
336 
337 /** out[i]=in[i]-floor(in[i])
338  */
339 template<typename T, unsigned D>
341 {
342  simd::remainder(&(in[0][0]), &(out[0][0]), in.size() * D);
343 }
344 } // namespace qmcplusplus
345 #endif
Fixed-size array.
Definition: OhmmsTinyMeta.h:30
static void apply(const Transformer_t &X, const Array_t &pin, Array_t &pout, int first, int last)
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
Dummy template class to be specialized.
static void Cart2Cart(const Array_t &pin, const Transformer_t &G, const Transformer_t &R, Array_t &pout, int first, int last)
static void apply(Array_t &pinout, const Transformer_t &X, int first, int last)
Dummy template class to apply boundary conditions.
static void apply(Array_t &pinout, const Transformer_t &X, int first, int last)
static void Cart2Unit(const Array_t &pin, const Transformer_t &G, Array_t &pout, int first, int last)
static void apply(const Transformer_t &X, Array_t &pinout, int first, int last)
Attaches a unit to a Vector for IO.
#define SUPERCELL_BOUNDARY_LIMITS(T)
Tensor<T,D> class for D by D tensor.
Definition: OhmmsTinyMeta.h:32
static Component_t Unit2Cart(const Component_t &pos, const Transformer_t &R)
#define THREE_DIM_BOUNDARY_BLOCK(X, Y, Z, EPS, PLUSONE)
static void apply(const Transformer_t &X, Array_t &pinout, int first, int last)
static void Unit2Unit(const Array_t &pin, Array_t &pout, int first, int last)
static Component_t Cart2Unit(const Component_t &pos, const Transformer_t &G)
void put2box(ParticleAttrib< TinyVector< T, D >> &inout)
inout[i]=inout[i]-floor(inout[i])
static void apply(const Array_t &pin, const Transformer_t &X, Array_t &pout, int first, int last)
void remainder(const T *restrict in, T *restrict out, SIZET n)
mod on an array out[i]=in[i]-floor(in[i])
Definition: vmath.hpp:38
static void Unit2Cart(const Array_t &pin, const Transformer_t &R, Array_t &pout, int first, int last)
static void apply(const Array_t &pin, const Transformer_t &X, Array_t &pout, int first, int last)
static Component_t Cart2Cart(const Component_t &pos, const Transformer_t &G, const Transformer_t &R)
static void Cart2Cart(Array_t &pinout, const Transformer_t &G, const Transformer_t &R, int first, int last)
static void apply(const Transformer_t &X, const Array_t &pin, Array_t &pout, int first, int last)