1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
11 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
12 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
13 * Copyright (c) 2001-2004, The GROMACS development team,
14 * check out http://www.gromacs.org for more information.
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * If you want to redistribute modifications, please consider that
22 * scientific software is very special. Version control is crucial -
23 * bugs must be traceable. We will be happy to consider code for
24 * inclusion in the official distribution, but derived work must not
25 * be called official GROMACS. Details are found in the README & COPYING
26 * files - if they are missing, get the official version at www.gromacs.org.
28 * To help us fund GROMACS development, we humbly ask that you cite
29 * the papers on the package - you can find them in the top README file.
31 * For more info, check our website at http://www.gromacs.org
34 * GROningen Mixture of Alchemy and Childrens' Stories
46 gmx_nb_free_energy_kernel(int icoul,
82 int n,ii,is3,ii3,k,nj0,nj1,jnr,j3,ggid;
84 real Fscal,FscalA,FscalB,tx,ty,tz;
85 real VcoulA,VcoulB,VvdwA,VvdwB;
88 real qqA,qqB,vcoul,vctot,krsq;
94 real ix,iy,iz,fix,fiy,fiz;
95 real dx,dy,dz,rsq,r4,r6,rinv;
96 real c6A,c12A,c6B,c12B;
97 real dvdl,L1,alfA,alfB,dalfA,dalfB;
99 real rA,rinvA,rinv4A,rB,rinvB,rinv4B;
100 int do_coultab,do_vdwtab,do_tab,tab_elemsize;
102 real Y,F,G,H,Fp,Geps,Heps2,eps,eps2,VV,FF;
103 double isp=0.564189583547756;
106 /* fix compiler warnings */
115 alfA = alpha*(lam_power==2 ? lambda*lambda : lambda);
116 alfB = alpha*(lam_power==2 ? L1*L1 : L1);
117 dalfA = alpha*lam_power/6.0*(lam_power==2 ? lambda : 1);
118 dalfB = alpha*lam_power/6.0*(lam_power==2 ? L1 : 1);
120 /* Ewald table is special (icoul==5) */
122 do_coultab = (icoul==3);
123 do_vdwtab = (ivdw==3);
125 do_tab = do_coultab || do_vdwtab;
127 /* we always use the combined table here */
130 for(n=0; (n<nri); n++)
134 shY = shiftvec[is3+1];
135 shZ = shiftvec[is3+2];
143 iqA = facel*chargeA[ii];
144 iqB = facel*chargeB[ii];
145 ntiA = 2*ntype*typeA[ii];
146 ntiB = 2*ntype*typeB[ii];
153 for(k=nj0; (k<nj1); k++)
160 rsq = dx*dx+dy*dy+dz*dz;
161 rinv = gmx_invsqrt(rsq);
163 tjA = ntiA+2*typeA[jnr];
164 tjB = ntiB+2*typeB[jnr];
169 qqA = iqA*chargeA[jnr];
170 qqB = iqB*chargeB[jnr];
172 if((c6A > 0) && (c12A > 0))
176 if (sigma6a < sigma6_min)
178 sigma6a = sigma6_min;
183 sigma6a = sigma6_def;
185 if((c6B > 0) && (c12B > 0))
189 if (sigma6b < sigma6_min)
191 sigma6b = sigma6_min;
196 sigma6b = sigma6_def;
207 /* Only spend time on A state if it is non-zero */
208 if( (qqA != 0) || (c6A != 0) || (c12A != 0) )
210 rA = pow(alfA*sigma6a+r6,1.0/6.0);
212 rinv4A = rinvA*rinvA;
213 rinv4A = rinv4A*rinv4A;
222 n1 = tab_elemsize*n0;
225 if(icoul==1 || icoul==5)
229 FscalA = VcoulA*rinvA*rinvA;
235 VcoulA = qqA*(rinvA+krsq-crf);
236 FscalA = qqA*(rinvA-2.0*krsq)*rinvA*rinvA;
240 /* non-Ewald tabulated coulomb */
244 Geps = eps*VFtab[nnn+2];
245 Heps2 = eps2*VFtab[nnn+3];
248 FF = Fp+Geps+2.0*Heps2;
250 FscalA = -qqA*tabscale*FF*rinvA;
256 rinv6 = rinvA*rinvA*rinv4A;
258 Vvdw12 = c12A*rinv6*rinv6;
259 VvdwA = Vvdw12-Vvdw6;
260 FscalA += (12.0*Vvdw12-6.0*Vvdw6)*rinvA*rinvA;
270 Geps = eps*VFtab[nnn+2];
271 Heps2 = eps2*VFtab[nnn+3];
274 FF = Fp+Geps+2.0*Heps2;
276 FscalA -= c6A*tabscale*FF*rinvA;
281 Geps = eps*VFtab[nnn+6];
282 Heps2 = eps2*VFtab[nnn+7];
285 FF = Fp+Geps+2.0*Heps2;
287 FscalA -= c12A*tabscale*FF*rinvA;
289 /* Buckingham vdw free energy not supported */
297 /* Only spend time on B state if it is non-zero */
298 if( (qqB != 0) || (c6B != 0) || (c12B != 0) )
300 rB = pow(alfB*sigma6b+r6,1.0/6.0);
302 rinv4B = rinvB*rinvB;
303 rinv4B = rinv4B*rinv4B;
312 n1 = tab_elemsize*n0;
315 if(icoul==1 || icoul==5)
319 FscalB = VcoulB*rinvB*rinvB;
325 VcoulB = qqB*(rinvB+krsq-crf);
326 FscalB = qqB*(rinvB-2.0*krsq)*rinvB*rinvB;
330 /* non-Ewald tabulated coulomb */
334 Geps = eps*VFtab[nnn+2];
335 Heps2 = eps2*VFtab[nnn+3];
338 FF = Fp+Geps+2.0*Heps2;
340 FscalB = -qqB*tabscale*FF*rinvB;
346 rinv6 = rinvB*rinvB*rinv4B;
348 Vvdw12 = c12B*rinv6*rinv6;
349 VvdwB = Vvdw12-Vvdw6;
350 FscalB += (12.0*Vvdw12-6.0*Vvdw6)*rinvB*rinvB;
360 Geps = eps*VFtab[nnn+2];
361 Heps2 = eps2*VFtab[nnn+3];
364 FF = Fp+Geps+2.0*Heps2;
366 FscalB -= c6B*tabscale*FF*rinvB;
371 Geps = eps*VFtab[nnn+6];
372 Heps2 = eps2*VFtab[nnn+7];
375 FF = Fp+Geps+2.0*Heps2;
377 FscalB -= c12B*tabscale*FF*rinvB;
379 /* Buckingham vdw free energy not supported */
386 /* Soft-core Ewald interactions are special:
387 * For the direct space interactions we effectively want the
388 * normal coulomb interaction (added above when icoul==5),
389 * but need to subtract the part added in reciprocal space.
393 VV = gmx_erf(ewc*r)*rinv;
394 FF = rinv*rinv*(VV - 2.0*ewc*isp*exp(-ewc*ewc*rsq));
398 VV = ewc*2.0/sqrt(M_PI);
401 vctot -= (lambda*qqB + L1*qqA)*VV;
402 Fscal -= (lambda*qqB + L1*qqA)*FF;
403 dvdl -= (qqB - qqA)*VV;
406 /* Assemble A and B states */
407 vctot += lambda*VcoulB + L1*VcoulA;
408 Vvdwtot += lambda*VvdwB + L1*VvdwA;
410 Fscal += (L1*FscalA*rinv4A + lambda*FscalB*rinv4B)*r4;
411 dvdl += (VcoulB + VvdwB) - (VcoulA + VvdwA);
412 dvdl += lambda*dalfB*FscalB*sigma6b*rinv4B
413 - L1*dalfA*FscalA*sigma6a*rinv4A;
424 f[j3+1] = f[j3+1] - ty;
425 f[j3+2] = f[j3+2] - tz;
431 f[ii3] = f[ii3] + fix;
432 f[ii3+1] = f[ii3+1] + fiy;
433 f[ii3+2] = f[ii3+2] + fiz;
434 fshift[is3] = fshift[is3] + fix;
435 fshift[is3+1] = fshift[is3+1] + fiy;
436 fshift[is3+2] = fshift[is3+2] + fiz;
439 Vc[ggid] = Vc[ggid] + vctot;
440 Vvdw[ggid] = Vvdw[ggid] + Vvdwtot;