Tinker9 70bd052 (Thu Nov 9 12:11:35 2023 -0800)
Loading...
Searching...
No Matches
pair_disp.h
1#pragma once
2#include "ff/elec.h"
3#include "math/libfunc.h"
4#include "math/switch.h"
5#include "seq/add.h"
6#include "seq/damp_hippodisp.h"
7#include "seq/pair_vlambda.h"
8#include "seq/seq.h"
9
10namespace tinker {
11#pragma acc routine seq
12template <bool DO_G, class DTYP, int SCALE>
15 real r2,
16 real rr1,
17 real dspscale,
18 real aewald,
19 real ci,
20 real ai,
21 real ck,
22 real ak,
23 real edcut,
24 real edoff,
25 real& restrict e,
26 real& restrict de)
27{
28 if (r > edoff) {
29 e = 0;
30 if CONSTEXPR (DO_G)
31 de = 0;
32 return;
33 }
34
35#if TINKER_REAL_SIZE == 8
36 real eps = 0.001f;
37#elif TINKER_REAL_SIZE == 4
38 real eps = 0.05f;
39#endif
40
41 real diff = REAL_ABS(ai - ak);
42 real rr2 = rr1 * rr1;
43 real rr6 = rr2 * rr2 * rr2;
44 real di = ai * r;
45 real dk = ak * r;
46 real expi = REAL_EXP(-di);
47 real expk = REAL_EXP(-dk);
48 real di2 = di * di;
49 real damp = 1, ddamp = 0;
50 if (diff > eps) {
51 real ai2 = ai * ai;
52 real ak2 = ak * ak;
53 real ti = ak2 * REAL_RECIP((ak + ai) * (ak - ai));
54 real tk = ai2 * REAL_RECIP((ai + ak) * (ai - ak));
55 real a1 = 2 * ti + 1;
56 real b1 = 2 * tk + 1;
57 real termi = ((di / 2 + b1) / 2 * di + b1) * di + b1;
58 real termk = ((dk / 2 + a1) / 2 * dk + a1) * dk + a1;
59 termi *= ti * ti * expi;
60 termk *= tk * tk * expk;
61 damp = 1 - termi - termk;
62 if CONSTEXPR (DO_G) {
63 real dk2 = dk * dk;
64 real a2 = (di - 1) / 4 + tk;
65 real b2 = (dk - 1) / 4 + ti;
66 a2 *= ai * di2 * ti * ti * expi;
67 b2 *= ak * dk2 * tk * tk * expk;
68 ddamp = a2 + b2;
69 }
70 } else {
71 ai = (ai + ak) * 0.5f;
72 di = ai * r;
73 di2 = di * di;
74 expi = REAL_EXP(-di);
75 real term = ((((di + 5) * di + 17) * di / 96 + 0.5f) * di + 1) * di + 1;
76 damp = 1 - term * expi;
77 if CONSTEXPR (DO_G)
78 ddamp = ai * expi * di2 * ((di2 - 3) * di - 3) / 96;
79 }
80
81 if CONSTEXPR (SCALE == 1)
82 dspscale = 1;
83
84 if CONSTEXPR (eq<DTYP, DEWALD>()) {
85 real ralpha2 = r2 * aewald * aewald;
86 real term = 1 + ralpha2 + 0.5f * ralpha2 * ralpha2;
87 real expterm = REAL_EXP(-ralpha2);
88 real expa = expterm * term;
89 e = -ci * ck * rr6 * (dspscale * damp * damp + expa - 1);
90 if CONSTEXPR (DO_G) {
91 real rterm = -ralpha2 * ralpha2 * ralpha2 * rr1 * expterm;
92 de = -6 * e * rr1 - ci * ck * rr6 * (rterm + 2 * dspscale * damp * ddamp);
93 }
94 } else if CONSTEXPR (eq<DTYP, NON_EWALD_TAPER>()) {
95 e = -ci * ck * rr6;
96 if CONSTEXPR (DO_G) {
97 de = -6 * e * rr1;
98 de = de * damp * damp + 2 * e * damp * ddamp;
99 }
100 e = e * damp * damp;
101 if (r > edcut) {
102 real taper, dtaper;
103 switchTaper5<DO_G>(r, edcut, edoff, taper, dtaper);
104 if CONSTEXPR (DO_G)
105 de = e * dtaper + de * taper;
106 e = e * taper;
107 }
108 e *= dspscale;
109 if CONSTEXPR (DO_G)
110 de *= dspscale;
111 }
112}
113
114#pragma acc routine seq
115template <bool DO_G, class DTYP, int SCALE, int SOFTCORE>
118 real r2,
119 real rr1,
120 real dspscale,
121 real aewald,
122 real ci,
123 real ai,
124 real ck,
125 real ak,
126 real vlambda,
127 real edcut,
128 real edoff,
129 real& restrict e,
130 real& restrict de)
131{
132 if (r > edoff) {
133 e = 0;
134 if CONSTEXPR (DO_G)
135 de = 0;
136 return;
137 }
138
139 real rr2 = rr1 * rr1;
140 real rr6 = rr2 * rr2 * rr2;
141 real dmpik[2], damp, ddamp;
142 damp_hippodisp<DO_G>(dmpik, r, rr1, ai, ak);
143 damp = dmpik[0];
144 if CONSTEXPR (DO_G)
145 ddamp = dmpik[1];
146
147 if CONSTEXPR (SCALE == 1)
148 dspscale = 1;
149
150 // set use of lambda scaling for decoupling or annihilation
151 if CONSTEXPR (SOFTCORE) {
152 real vlambda2 = vlambda * vlambda;
153 real vlambda3 = vlambda2 * vlambda;
154 real vterm = (vlambda2 * vlambda2) / REAL_SQRT(1.0 + vlambda2 - vlambda3);
155 dspscale *= vterm;
156 }
157
158 if CONSTEXPR (eq<DTYP, DEWALD>()) {
159 real ralpha2 = r2 * aewald * aewald;
160 real term = 1 + ralpha2 + 0.5f * ralpha2 * ralpha2;
161 real expterm = REAL_EXP(-ralpha2);
162 real expa = expterm * term;
163 e = -ci * ck * rr6 * (dspscale * damp * damp + expa - 1);
164 if CONSTEXPR (DO_G) {
165 real rterm = -ralpha2 * ralpha2 * ralpha2 * rr1 * expterm;
166 de = -6 * e * rr1 - ci * ck * rr6 * (rterm + 2 * dspscale * damp * ddamp);
167 }
168 } else if CONSTEXPR (eq<DTYP, NON_EWALD_TAPER>()) {
169 e = -ci * ck * rr6;
170 if CONSTEXPR (DO_G) {
171 de = -6 * e * rr1;
172 de = de * damp * damp + 2 * e * damp * ddamp;
173 }
174 e = e * damp * damp;
175 if (r > edcut) {
176 real taper, dtaper;
177 switchTaper5<DO_G>(r, edcut, edoff, taper, dtaper);
178 if CONSTEXPR (DO_G)
179 de = e * dtaper + de * taper;
180 e = e * taper;
181 }
182 e *= dspscale;
183 if CONSTEXPR (DO_G)
184 de *= dspscale;
185 }
186}
187}
#define SEQ_CUDA
Definition: acc/seqdef.h:12
real * ak
#define restrict
Definition: macro.h:51
#define CONSTEXPR
Definition: macro.h:61
float real
Definition: precision.h:80
Definition: testrt.h:9
__device__ void pair_disp_obsolete(real r, real r2, real rr1, real dspscale, real aewald, real ci, real ai, real ck, real ak, real edcut, real edoff, real &__restrict__ e, real &__restrict__ de)
Definition: pair_disp.h:14
__device__ void pair_disp(real r, real r2, real rr1, real dspscale, real aewald, real ci, real ai, real ck, real ak, real vlambda, real edcut, real edoff, real &__restrict__ e, real &__restrict__ de)
Definition: pair_disp.h:117