NAMD
Lattice.h
Go to the documentation of this file.
1 
7 #ifndef LATTICE_H
8 #define LATTICE_H
9 
10 #include <stdlib.h>
11 #include "NamdTypes.h"
12 #include <math.h>
13 #include "Tensor.h"
14 
16 
17 class Lattice
18 {
19 public:
20  Lattice(void) : a1(0,0,0), a2(0,0,0), a3(0,0,0),
21  b1(0,0,0), b2(0,0,0), b3(0,0,0),
22  o(0,0,0), p1(0), p2(0), p3(0) {};
23 
24  // maps a transformation triplet onto a single integer
25  NAMD_HOST_DEVICE static int index(int i=0, int j=0, int k=0)
26  {
27  return 9 * (k+1) + 3 * (j+1) + (i+1);
28  }
29 
30  // sets lattice basis vectors but not origin (fixed center)
32  {
33  set(A,B,C,o);
34  }
35 
36  // sets lattice basis vectors and origin (fixed center)
38  {
39  a1 = A; a2 = B; a3 = C; o = Origin;
40  p1 = ( a1.length2() ? 1 : 0 );
41  p2 = ( a2.length2() ? 1 : 0 );
42  p3 = ( a3.length2() ? 1 : 0 );
43  if ( ! p1 ) a1 = Vector(1.0,0.0,0.0);
44  if ( ! p2 ) {
45  Vector u1 = a1 / a1.length();
46  Vector e_z(0.0,0.0,1.0);
47  if ( fabs(e_z * u1) < 0.9 ) { a2 = cross(e_z,a1); }
48  else { a2 = cross(Vector(1.0,0.0,0.0),a1); }
49  a2 /= a2.length();
50  }
51  if ( ! p3 ) {
52  a3 = cross(a1,a2);
53  a3 /= a3.length();
54  }
55  if ( volume() < 0.0 ) a3 *= -1.0;
56  recalculate();
57  }
58 
59  // rescale lattice dimensions by factor, origin doesn't move
61  {
62  a1 = factor * a1;
63  a2 = factor * a2;
64  a3 = factor * a3;
65  recalculate();
66  }
67 
68  // rescale a position, keeping origin constant, assume 3D
69  NAMD_HOST_DEVICE void rescale(Position &p, Tensor factor) const
70  {
71  p -= o;
72  p = factor * p;
73  p += o;
74  }
75 
76  // transform scaled position to unscaled position
78  {
79  return (o + a1*s.x + a2*s.y + a3*s.z);
80  }
81 
82  // transform unscaled position to scaled position
84  {
85  p -= o;
86  return Vector(b1*p,b2*p,b3*p);
87  }
88 
90  {
91  return (f.x*b1 + f.y*b2 + f.z*b3); // calculating A^(-1)f for PME force contributions
92  }
93 
94  // transforms a position nearest to a SCALED reference position
96  {
97  ScaledPosition sn = scale(data);
98  if ( p1 ) {
99  sn.x -= namdnearbyint(sn.x - ref.x);
100  }
101  if ( p2 ) {
102  sn.y -= namdnearbyint(sn.y - ref.y);
103  }
104  if ( p3 ) {
105  sn.z -= namdnearbyint(sn.z - ref.z);
106  }
107  return unscale(sn);
108  }
109 
110  // transforms a position nearest to a SCALED reference position
111  // adds transform for later reversal
113  {
114  ScaledPosition sn = scale(data);
115  if ( p1 ) {
116  BigReal tmp = sn.x - ref.x;
117  BigReal rit = namdnearbyint(tmp);
118  sn.x -= rit;
119  t->i -= (int) rit;
120  }
121  if ( p2 ) {
122  BigReal tmp = sn.y - ref.y;
123  BigReal rit = namdnearbyint(tmp);
124  sn.y -= rit;
125  t->j -= (int) rit;
126  }
127  if ( p3 ) {
128  BigReal tmp = sn.z - ref.z;
129  BigReal rit = namdnearbyint(tmp);
130  sn.z -= rit;
131  t->k -= (int) rit;
132  }
133  return unscale(sn);
134  }
135 
136  // applies stored transform to original coordinates
138  {
139  return ( data + t.i*a1 + t.j*a2 + t.k*a3 );
140  }
141 
142  // reverses cumulative transformations for output
144  {
145  return ( data - t.i*a1 - t.j*a2 - t.k*a3 );
146  }
147 
148  // calculates shortest vector from p2 to p1 (equivalent to p1 - p2)
149  NAMD_HOST_DEVICE Vector delta(const Position &pos1, const Position &pos2) const
150  {
151  Vector diff = pos1 - pos2;
152  return delta_from_diff(diff);
153  }
154 
155  // calculates shortest vector for given distance vector
157  {
158  Vector diff = diff_in;
159 #ifdef ARCH_POWERPC //Prevents stack temporaries
160  Vector result = diff;
161  if ( p1 ) {
162  BigReal fval = namdnearbyint(b1*diff);
163  result.x -= a1.x *fval;
164  result.y -= a1.y *fval;
165  result.z -= a1.z *fval;
166  }
167  if ( p2 ) {
168  BigReal fval = namdnearbyint(b2*diff);
169  result.x -= a2.x * fval;
170  result.y -= a2.y * fval;
171  result.z -= a2.z * fval;
172  }
173  if ( p3 ) {
174  BigReal fval = namdnearbyint(b3*diff);
175  result.x -= a3.x * fval;
176  result.y -= a3.y * fval;
177  result.z -= a3.z * fval;
178  }
179  return result;
180 #else
181  BigReal f1 = p1 ? namdnearbyint(b1*diff) : 0.;
182  BigReal f2 = p2 ? namdnearbyint(b2*diff) : 0.;
183  BigReal f3 = p3 ? namdnearbyint(b3*diff) : 0.;
184  diff.x -= f1*a1.x + f2*a2.x + f3*a3.x;
185  diff.y -= f1*a1.y + f2*a2.y + f3*a3.y;
186  diff.z -= f1*a1.z + f2*a2.z + f3*a3.z;
187  return diff;
188 #endif
189  }
190 
191  // calculates scaled vector v such that vector pos1 - pos2 + v*a is the shortest
193  {
194  Vector diff = pos1 - pos2;
195  Vector result(0.,0.,0.);
196 
197  if ( p1 ) result.x = -namdnearbyint(b1*diff);
198  if ( p2 ) result.y = -namdnearbyint(b2*diff);
199  if ( p3 ) result.z = -namdnearbyint(b3*diff);
200  return result;
201  }
202 
204  {
205  Vector diff = pos1 - pos2;
206  Vector result(-namdnearbyint(b1*diff), -namdnearbyint(b2*diff), -namdnearbyint(b3*diff));
207  return result;
208  }
209 
210  // calculates shortest vector from origin to p1 (equivalent to p1 - o)
212  {
213  Vector diff = pos1 - o;
214  Vector result = diff;
215  if ( p1 ) result -= a1*namdnearbyint(b1*diff);
216  if ( p2 ) result -= a2*namdnearbyint(b2*diff);
217  if ( p3 ) result -= a3*namdnearbyint(b3*diff);
218  return result;
219  }
220 
221  // calculates vector to bring p1 closest to origin
223  {
224  Vector diff = pos1 - o;
225  Vector result(0.,0.,0.);
226  if ( p1 ) result -= a1*namdnearbyint(b1*diff);
227  if ( p2 ) result -= a2*namdnearbyint(b2*diff);
228  if ( p3 ) result -= a3*namdnearbyint(b3*diff);
229  return result;
230  }
231 
232  // calculates vector to bring p1 closest to origin in unscaled coordinates
234  {
235  Vector diff = pos1 - o;
236  Vector result0(0.,0.,0.);
237  if ( p1 ) result0 -= a1*namdnearbyint(b1*diff);
238  if ( p2 ) result0 -= a2*namdnearbyint(b2*diff);
239  if ( p3 ) result0 -= a3*namdnearbyint(b3*diff);
240  diff += result0;
241  BigReal dist = diff.length2();
242  Vector result(0.,0.,0.);
243  for ( int i1=-p1; i1<=p1; ++i1 ) {
244  for ( int i2 =-p2; i2<=p2; ++i2 ) {
245  for ( int i3 =-p3; i3<=p3; ++i3 ) {
246  Vector newresult = i1*a1+i2*a2+i3*a3;
247  BigReal newdist = (diff+newresult).length2();
248  if ( newdist < dist ) {
249  dist = newdist;
250  result = newresult;
251  }
252  }
253  }
254  }
255  return result0 + result;
256  }
257 
259  {
260  return ( (i%3-1) * a1 + ((i/3)%3-1) * a2 + (i/9-1) * a3 );
261  }
262 
263  NAMD_HOST_DEVICE static int offset_a(int i) { return (i%3-1); }
264  NAMD_HOST_DEVICE static int offset_b(int i) { return ((i/3)%3-1); }
265  NAMD_HOST_DEVICE static int offset_c(int i) { return (i/9-1); }
266 
267  // lattice vectors
268  NAMD_HOST_DEVICE Vector a() const { return a1; }
269  NAMD_HOST_DEVICE Vector b() const { return a2; }
270  NAMD_HOST_DEVICE Vector c() const { return a3; }
271 
272  // only if along x y z axes
274  return ( ! ( a1.y || a1.z || a2.x || a2.z || a3.x || a3.y ) );
275  }
276 
277  // origin (fixed center of cell)
279  {
280  return o;
281  }
282 
283  // reciprocal lattice vectors
284  NAMD_HOST_DEVICE Vector a_r() const { return b1; }
285  NAMD_HOST_DEVICE Vector b_r() const { return b2; }
286  NAMD_HOST_DEVICE Vector c_r() const { return b3; }
287 
288  // periodic along this direction
289  NAMD_HOST_DEVICE int a_p() const { return p1; }
290  NAMD_HOST_DEVICE int b_p() const { return p2; }
291  NAMD_HOST_DEVICE int c_p() const { return p3; }
292 
294  {
295  return ( p1 && p2 && p3 ? cross(a1,a2) * a3 : 0.0 );
296  }
297 
298  bool isEqual(const Lattice& other) const {
299  return (a1 == other.a1) &&
300  (a2 == other.a2) &&
301  (a3 == other.a3) &&
302  (o == other.o);
303  }
304 
305 private:
306  Vector a1,a2,a3; // real lattice vectors
307  Vector b1,b2,b3; // reciprocal lattice vectors (more or less)
308  Vector o; // origin (fixed center of cell)
309  int p1, p2, p3; // periodic along this lattice vector?
310 
311  // calculate reciprocal lattice vectors
312  NAMD_HOST_DEVICE void recalculate(void) {
313  {
314  Vector c = cross(a2,a3);
315  b1 = c / ( a1 * c );
316  }
317  {
318  Vector c = cross(a3,a1);
319  b2 = c / ( a2 * c );
320  }
321  {
322  Vector c = cross(a1,a2);
323  b3 = c / ( a3 * c );
324  }
325  }
326 
327 };
328 
329 #endif
330 
bool isEqual(const Lattice &other) const
Definition: Lattice.h:298
NAMD_HOST_DEVICE void rescale(Tensor factor)
Definition: Lattice.h:60
#define namdnearbyint(x)
Definition: common.h:85
NAMD_HOST_DEVICE Vector c() const
Definition: Lattice.h:270
NAMD_HOST_DEVICE void rescale(Position &p, Tensor factor) const
Definition: Lattice.h:69
static NAMD_HOST_DEVICE int index(int i=0, int j=0, int k=0)
Definition: Lattice.h:25
NAMD_HOST_DEVICE Position reverse_transform(Position data, const Transform &t) const
Definition: Lattice.h:143
NAMD_HOST_DEVICE int c_p() const
Definition: Lattice.h:291
Definition: Vector.h:72
NAMD_HOST_DEVICE Position unscale(ScaledPosition s) const
Definition: Lattice.h:77
BigReal z
Definition: Vector.h:74
int8 i
Definition: NamdTypes.h:44
int8 j
Definition: NamdTypes.h:44
NAMD_HOST_DEVICE int orthogonal() const
Definition: Lattice.h:273
Lattice(void)
Definition: Lattice.h:20
NAMD_HOST_DEVICE int b_p() const
Definition: Lattice.h:290
#define NAMD_HOST_DEVICE
Definition: common.h:237
static NAMD_HOST_DEVICE int offset_b(int i)
Definition: Lattice.h:264
NAMD_HOST_DEVICE BigReal length(void) const
Definition: Vector.h:202
NAMD_HOST_DEVICE Position apply_transform(Position data, const Transform &t) const
Definition: Lattice.h:137
static NAMD_HOST_DEVICE int offset_c(int i)
Definition: Lattice.h:265
AtomID Origin
Definition: ComputeQM.h:110
NAMD_HOST_DEVICE ScaledPosition scale(Position p) const
Definition: Lattice.h:83
NAMD_HOST_DEVICE BigReal length2(void) const
Definition: Vector.h:206
BigReal x
Definition: Vector.h:74
NAMD_HOST_DEVICE Vector wrap_delta_scaled(const Position &pos1, const Position &pos2) const
Definition: Lattice.h:192
NAMD_HOST_DEVICE BigReal volume(void) const
Definition: Lattice.h:293
NAMD_HOST_DEVICE int a_p() const
Definition: Lattice.h:289
NAMD_HOST_DEVICE Vector a_r() const
Definition: Lattice.h:284
NAMD_HOST_DEVICE Vector b_r() const
Definition: Lattice.h:285
NAMD_HOST_DEVICE Position nearest(Position data, ScaledPosition ref) const
Definition: Lattice.h:95
NAMD_HOST_DEVICE Vector offset(int i) const
Definition: Lattice.h:258
NAMD_HOST_DEVICE Vector c_r() const
Definition: Lattice.h:286
NAMD_HOST_DEVICE Vector b() const
Definition: Lattice.h:269
Vector ScaledPosition
Definition: Lattice.h:15
NAMD_HOST_DEVICE Vector wrap_delta_scaled_fast(const Position &pos1, const Position &pos2) const
Definition: Lattice.h:203
static NAMD_HOST_DEVICE int offset_a(int i)
Definition: Lattice.h:263
Definition: Tensor.h:15
NAMD_HOST_DEVICE Vector delta(const Position &pos1) const
Definition: Lattice.h:211
BigReal y
Definition: Vector.h:74
NAMD_HOST_DEVICE Vector wrap_nearest_delta(Position pos1) const
Definition: Lattice.h:233
NAMD_HOST_DEVICE Vector delta_from_diff(const Position &diff_in) const
Definition: Lattice.h:156
NAMD_HOST_DEVICE Vector a() const
Definition: Lattice.h:268
NAMD_HOST_DEVICE Vector wrap_delta(const Position &pos1) const
Definition: Lattice.h:222
NAMD_HOST_DEVICE Vector origin() const
Definition: Lattice.h:278
NAMD_HOST_DEVICE Vector scale_force(Vector f) const
Definition: Lattice.h:89
int8 k
Definition: NamdTypes.h:44
double BigReal
Definition: common.h:123
NAMD_HOST_DEVICE Vector delta(const Position &pos1, const Position &pos2) const
Definition: Lattice.h:149
NAMD_HOST_DEVICE Position nearest(Position data, ScaledPosition ref, Transform *t) const
Definition: Lattice.h:112