14 int K1, K2, K3,
order;
21 switch (myGrid.
order) {
23 compute_b_moduli<4>(bm1, K1);
24 compute_b_moduli<4>(bm2, K2);
25 compute_b_moduli<4>(bm3, K3);
28 compute_b_moduli<6>(bm1, K1);
29 compute_b_moduli<6>(bm2, K2);
30 compute_b_moduli<6>(bm3, K3);
33 compute_b_moduli<8>(bm1, K1);
34 compute_b_moduli<8>(bm2, K2);
35 compute_b_moduli<8>(bm3, K3);
38 compute_b_moduli<10>(bm1, K1);
39 compute_b_moduli<10>(bm2, K2);
40 compute_b_moduli<10>(bm3, K3);
42 default:
NAMD_die(
"unsupported LJPMEInterpOrder");
53 double ewald,
double *virial) {
65 int maxK1, maxK2, maxK3;
67 K1=myGrid.
K1; K2=myGrid.
K2; K3=myGrid.
K3;
68 maxK1 = K1/2; maxK2 = K2/2; maxK3 = K3/2;
71 double beta3 = ewald*ewald*ewald;
73 double fac2 = -
M_PI*
M_PI/(ewald*ewald);
75 double fac4 =
M_PI/ewald;
82 double recipx = lattice.
a_r().
x;
83 double recipy = lattice.
b_r().
y;
84 double recipz = lattice.
c_r().
z;
88 for ( k1=0; k1<K1; ++k1 ) {
92 int k1_s = k1<=maxK1 ? k1 : k1-K1;
95 for ( k2=0; k2<K2; ++k2 ) {
99 int k2_s = k2<=maxK2 ? k2 : k2-K2;
103 for ( k3=0; k3<=maxK3; ++k3 ) {
104 double m3, m33, msq, mFreq, vir, tempE;
105 double b1b2b3, eTerm, q2, qr, qc;
107 b1b2b3 = bm3[k3] *b1b2;
111 msq = m11 + m22 + m33;
113 qr = q_arr[ind]; qc=q_arr[ind+1];
115 q2 = 2.0*(qr*qr + qc*qc);
117 if ( (k3 == 0) || ( k3 == maxK3 && ! (K3 & 1) ) ) q2 *= 0.5;
119 eTerm = b1b2b3*box_factor*((beta3 + fac1*msq)*exp(fac2*msq) + fac3*msq*mFreq*erfc(fac4*mFreq));
122 q_arr[ind+1] *= eTerm;
127 vir = 3.0*box_factor*b1b2b3*(fac1*exp(fac2*msq)+fac3*mFreq*erfc(fac4*mFreq))*q2;
128 v0 += tempE + vir*m11;
131 v3 += tempE + vir*m22;
133 v5 += tempE + vir*m33;
143 double recip2_x = recip2.
x;
144 double recip2_y = recip2.
y;
145 double recip2_z = recip2.
z;
146 double recip3_x = recip3.
x;
147 double recip3_y = recip3.
y;
148 double recip3_z = recip3.
z;
151 for ( k1=0; k1<K1; ++k1 ) {
155 int k1_s = k1<=maxK1 ? k1 : k1-K1;
157 for ( k2=0; k2<K2; ++k2 ) {
158 double b1b2, m2_x, m2_y, m2_z;
161 int k2_s = k2<=maxK2 ? k2 : k2-K2;
162 m2_x = m1.
x + k2_s*recip2_x;
163 m2_y = m1.
y + k2_s*recip2_y;
164 m2_z = m1.
z + k2_s*recip2_z;
166 for ( k3=0; k3<=maxK3; ++k3 ) {
167 double xp3, msq, mFreq, vir, tempE;
168 double b1b2b3, eTerm, q2, qr, qc;
169 double m_x, m_y, m_z;
171 b1b2b3 = bm3[k3] *b1b2;
172 m_x = m2_x + k3*recip3_x;
173 m_y = m2_y + k3*recip3_y;
174 m_z = m2_z + k3*recip3_z;
176 msq = m_x*m_x + m_y*m_y + m_z*m_z;
178 qr = q_arr[ind]; qc=q_arr[ind+1];
180 q2 = 2.0*(qr*qr + qc*qc);
182 if ( (k3 == 0) || ( k3 == maxK3 && ! (K3 & 1) ) ) q2 *= 0.5;
184 eTerm = b1b2b3*box_factor*((beta3 + fac1*msq)*exp(fac2*msq) + fac3*msq*mFreq*erfc(fac4*mFreq));
187 q_arr[ind+1] *= eTerm;
192 vir = 3.0*box_factor*b1b2b3*(fac1*exp(fac2*msq)+fac3*mFreq*erfc(fac4*mFreq))*q2;
193 v0 += tempE + vir*m_x*m_x;
196 v3 += tempE + vir*m_y*m_y;
198 v5 += tempE + vir*m_z*m_z;
206 virial[0] = 0.5 * v0;
207 virial[1] = 0.5 * v1;
208 virial[2] = 0.5 * v2;
209 virial[3] = 0.5 * v3;
210 virial[4] = 0.5 * v4;
211 virial[5] = 0.5 * v5;
216 void LjPmeKSpace::compute_b_moduli(
double *bm,
int K) {
220 double *M =
new double[3*
order];
221 double *dM =
new double[3*
order];
222 double *scratch =
new double[K];
224 fr[0]=fr[1]=fr[2]=0.0;
225 compute_LjPme_b_spline<order>(fr,M,dM);
226 for (i=0; i<
order; i++) bm[i] = M[i];
227 for (i=
order; i<K; i++) bm[i] = 0.0;
228 this->dftmod(scratch, bm, K);
230 for (i=0; i<K; i++) bm[i] = 1.0/scratch[i];
237 void LjPmeKSpace::dftmod(
double *bsp_mod,
double *bsp_arr,
int nfft) {
239 double twopi, arg, sum1, sum2;
240 double infft = 1.0/nfft;
245 for (k = 0; k <nfft; ++k) {
248 for (j = 0; j < nfft; ++j) {
249 arg = twopi * k * j * infft;
250 sum1 += bsp_arr[j] * cos(arg);
251 sum2 += bsp_arr[j] * sin(arg);
253 bsp_mod[k] = sum1*sum1 + sum2*sum2;
NAMD_HOST_DEVICE int orthogonal() const
double compute_energy(float *q_arr, const Lattice &lattice, double ewald, double *virial)
NAMD_HOST_DEVICE BigReal volume(void) const
NAMD_HOST_DEVICE Vector a_r() const
NAMD_HOST_DEVICE Vector b_r() const
void NAMD_die(const char *err_msg)
NAMD_HOST_DEVICE Vector c_r() const
LjPmeKSpace(LjPmeGrid grid)