Tinker9 70bd052 (Thu Nov 9 12:11:35 2023 -0800)
Loading...
Searching...
No Matches
improp.h
1#pragma once
2#include "math/const.h"
3#include "math/libfunc.h"
4#include "seq/add.h"
5#include "seq/seq.h"
6
7namespace tinker {
8// Computing angle from sine instead of cosine may have a higher precision.
9#pragma acc routine seq
10template <class Ver>
13 real& restrict vzx, real& restrict vyy, real& restrict vzy,
14 real& restrict vzz,
15
18
19 real idihunit, int i, const int (*restrict iiprop)[4],
20 const real* restrict kprop, const real* restrict vprop,
21
22 const real* restrict x, const real* restrict y, const real* restrict z)
23{
24 constexpr bool do_e = Ver::e;
25 constexpr bool do_g = Ver::g;
26 constexpr bool do_v = Ver::v;
27 if CONSTEXPR (do_e) e = 0;
28 if CONSTEXPR (do_v) vxx = 0, vyx = 0, vzx = 0, vyy = 0, vzy = 0, vzz = 0;
29
30 const int ia = iiprop[i][0];
31 const int ib = iiprop[i][1];
32 const int ic = iiprop[i][2];
33 const int id = iiprop[i][3];
34 real ideal = vprop[i];
35 real force = kprop[i];
36
37 real xia = x[ia];
38 real yia = y[ia];
39 real zia = z[ia];
40 real xib = x[ib];
41 real yib = y[ib];
42 real zib = z[ib];
43 real xic = x[ic];
44 real yic = y[ic];
45 real zic = z[ic];
46 real xid = x[id];
47 real yid = y[id];
48 real zid = z[id];
49 real xba = xib - xia;
50 real yba = yib - yia;
51 real zba = zib - zia;
52 real xcb = xic - xib;
53 real ycb = yic - yib;
54 real zcb = zic - zib;
55 real xdc = xid - xic;
56 real ydc = yid - yic;
57 real zdc = zid - zic;
58
59 real xt = yba * zcb - ycb * zba;
60 real yt = zba * xcb - zcb * xba;
61 real zt = xba * ycb - xcb * yba;
62 real xu = ycb * zdc - ydc * zcb;
63 real yu = zcb * xdc - zdc * xcb;
64 real zu = xcb * ydc - xdc * ycb;
65 real xtu = yt * zu - yu * zt;
66 real ytu = zt * xu - zu * xt;
67 real ztu = xt * yu - xu * yt;
68 real rt2 = xt * xt + yt * yt + zt * zt;
69 real ru2 = xu * xu + yu * yu + zu * zu;
70 real rtru = REAL_SQRT(rt2 * ru2);
71
72 if (rtru != 0) {
73 real rcb = REAL_SQRT(xcb * xcb + ycb * ycb + zcb * zcb);
74 real sine = (xcb * xtu + ycb * ytu + zcb * ztu) * REAL_RECIP(rcb * rtru);
75 real angle = radian * REAL_ASIN(sine);
76
77 if (REAL_ABS(angle + ideal) < REAL_ABS(angle - ideal)) ideal = -ideal;
78 real dt = angle - ideal;
79 if (dt > 180) dt -= 360;
80 if (dt < -180) dt += 360;
81
82 if CONSTEXPR (do_e) e = idihunit * force * dt * dt;
83
84 if CONSTEXPR (do_g) {
85 real dedphi = 2 * idihunit * force * dt * radian;
86 real xca = xic - xia;
87 real yca = yic - yia;
88 real zca = zic - zia;
89 real xdb = xid - xib;
90 real ydb = yid - yib;
91 real zdb = zid - zib;
92
93 real dedxt = dedphi * (yt * zcb - ycb * zt) * REAL_RECIP(rt2 * rcb);
94 real dedyt = dedphi * (zt * xcb - zcb * xt) * REAL_RECIP(rt2 * rcb);
95 real dedzt = dedphi * (xt * ycb - xcb * yt) * REAL_RECIP(rt2 * rcb);
96 real dedxu = -dedphi * (yu * zcb - ycb * zu) * REAL_RECIP(ru2 * rcb);
97 real dedyu = -dedphi * (zu * xcb - zcb * xu) * REAL_RECIP(ru2 * rcb);
98 real dedzu = -dedphi * (xu * ycb - xcb * yu) * REAL_RECIP(ru2 * rcb);
99
100 real dedxia = zcb * dedyt - ycb * dedzt;
101 real dedyia = xcb * dedzt - zcb * dedxt;
102 real dedzia = ycb * dedxt - xcb * dedyt;
103 real dedxib = yca * dedzt - zca * dedyt + zdc * dedyu - ydc * dedzu;
104 real dedyib = zca * dedxt - xca * dedzt + xdc * dedzu - zdc * dedxu;
105 real dedzib = xca * dedyt - yca * dedxt + ydc * dedxu - xdc * dedyu;
106 real dedxic = zba * dedyt - yba * dedzt + ydb * dedzu - zdb * dedyu;
107 real dedyic = xba * dedzt - zba * dedxt + zdb * dedxu - xdb * dedzu;
108 real dedzic = yba * dedxt - xba * dedyt + xdb * dedyu - ydb * dedxu;
109 real dedxid = zcb * dedyu - ycb * dedzu;
110 real dedyid = xcb * dedzu - zcb * dedxu;
111 real dedzid = ycb * dedxu - xcb * dedyu;
112
113 atomic_add(dedxia, deidx, ia);
114 atomic_add(dedyia, deidy, ia);
115 atomic_add(dedzia, deidz, ia);
116 atomic_add(dedxib, deidx, ib);
117 atomic_add(dedyib, deidy, ib);
118 atomic_add(dedzib, deidz, ib);
119 atomic_add(dedxic, deidx, ic);
120 atomic_add(dedyic, deidy, ic);
121 atomic_add(dedzic, deidz, ic);
122 atomic_add(dedxid, deidx, id);
123 atomic_add(dedyid, deidy, id);
124 atomic_add(dedzid, deidz, id);
125
126 if CONSTEXPR (do_v) {
127 vxx = xcb * (dedxic + dedxid) - xba * dedxia + xdc * dedxid;
128 vyx = ycb * (dedxic + dedxid) - yba * dedxia + ydc * dedxid;
129 vzx = zcb * (dedxic + dedxid) - zba * dedxia + zdc * dedxid;
130 vyy = ycb * (dedyic + dedyid) - yba * dedyia + ydc * dedyid;
131 vzy = zcb * (dedyic + dedyid) - zba * dedyia + zdc * dedyid;
132 vzz = zcb * (dedzic + dedzid) - zba * dedzia + zdc * dedzid;
133 }
134 }
135 }
136}
137}
void atomic_add(T value, T *buffer, size_t offset=0)
Definition: acc/adddef.h:14
#define SEQ_CUDA
Definition: acc/seqdef.h:12
#define restrict
Definition: macro.h:51
#define CONSTEXPR
Definition: macro.h:61
real * z
Current coordinates used in energy evaluation and neighbor lists.
real * x
Number of the trajectory frames.
real * y
Current coordinates used in energy evaluation and neighbor lists.
constexpr real radian
Definition: const.h:14
float real
Definition: precision.h:80
fixed grad_prec
Definition: precision.h:103
grad_prec * deidz
grad_prec * deidx
real * kprop
real * vprop
real idihunit
grad_prec * deidy
int(* iiprop)[4]
Definition: testrt.h:9
__device__ void dk_improp(real &__restrict__ e, real &__restrict__ vxx, real &__restrict__ vyx, real &__restrict__ vzx, real &__restrict__ vyy, real &__restrict__ vzy, real &__restrict__ vzz, grad_prec *__restrict__ deidx, grad_prec *__restrict__ deidy, grad_prec *__restrict__ deidz, real idihunit, int i, const int(*__restrict__ iiprop)[4], const real *__restrict__ kprop, const real *__restrict__ vprop, const real *__restrict__ x, const real *__restrict__ y, const real *__restrict__ z)
Definition: improp.h:12