4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
12 * Copyright (c) 1991-1999
13 * BIOSON Research Institute, Dept. of Biophysical Chemistry
14 * University of Groningen, The Netherlands
17 * GROMACS: A message-passing parallel molecular dynamics implementation
18 * H.J.C. Berendsen, D. van der Spoel and R. van Drunen
19 * Comp. Phys. Comm. 91, 43-56 (1995)
21 * Also check out our WWW page:
22 * http://md.chem.rug.nl/~gmx
27 * Green Red Orange Magenta Azure Cyan Skyblue
29 static char *SRCID_ewald_util_c
= "$Id$";
36 #include "ewald_util.h"
47 real
calc_ewaldcoeff(real rc
,real dtol
)
56 } while((erfc(x
*rc
)/rc
)>dtol
);
58 n
=i
+60; /* search tolerance is 2^-60 */
63 if((erfc(x
*rc
)/rc
)>dtol
)
73 real
ewald_LRcorrection(FILE *fp
,t_nsborder
*nsb
,t_commrec
*cr
,t_forcerec
*fr
,
74 real charge
[],t_block
*excl
,rvec x
[],
75 rvec box_size
,matrix lr_vir
)
77 static bool bFirst
=TRUE
;
80 int i
,i1
,i2
,j
,k
,m
,iv
,jv
;
82 double qq
; /* Necessary for precision */
83 real vc
,qi
,dr
,ddd
,dr2
,rinv
,fscal
,Vexcl
,rinv2
,ewc
=fr
->ewaldcoeff
;
88 real tabscale
=fr
->tabscale
;
89 real eps
,eps2
,VV
,FF
,F
,Y
,Geps
,Heps2
,Fp
,fijC
,r1t
;
90 real
*VFtab
=fr
->VFtab
;
93 double isp
=0.564189583547756;
96 int start
= START(nsb
);
97 int end
= start
+HOMENR(nsb
);
101 for(i
=start
; (i
<end
); i
++)
102 qq
+= charge
[i
]*charge
[i
];
104 /* Charge and dipole correction remain to be implemented... */
106 Vself
=ewc
*ONE_4PI_EPS0
*qq
/sqrt(M_PI
);
108 fprintf(fp
,"Long Range corrections for Ewald interactions:\n");
109 fprintf(fp
,"start=%d,natoms=%d\n",start
,end
-start
);
110 fprintf(fp
,"qq = %g, Vself=%g\n",qq
,Vself
);
117 for(i
=start
; (i
<end
); i
++) {
118 /* Initiate local variables (for this i-particle) to 0 */
119 qi
= charge
[i
]*ONE_4PI_EPS0
;
121 i2
= excl
->index
[i
+1];
122 /* Loop over excluded neighbours */
123 for(j
=i1
; (j
<i2
); j
++) {
126 * First we must test whether k <> i, and then, because the
127 * exclusions are all listed twice i->k and k->i we must select
128 * just one of the two.
129 * As a minor optimization we only compute forces when the charges
135 /* Compute distance vector, no PBC check! */
137 for(m
=0; (m
<DIM
); m
++) {
138 ddd
= x
[i
][m
] - x
[k
][m
];
139 if(ddd
>box_size
[m
]/2) { /* ugly hack, */
140 ddd
-=box_size
[m
]; /* to fix pbc.. */
141 /* Can this be done better? */
142 } else if (ddd
<-box_size
[m
]/2)
149 /* It might be possible to optimize this slightly
150 * when using spc or similar water models:
151 * Potential could be stored once, at the beginning,
152 * and forces could use that bonds are constant
154 /* The Ewald interactions are tabulated. If you
155 * remove the tabulation you must replace this
172 Geps
= eps
*VFtab
[nnn
+2];
173 Heps2
= eps2
*VFtab
[nnn
+3];
176 FF
= Fp
+Geps
+2.0*Heps2
;
181 fscal
= vc
*rinv2
+fijC
*tabscale
*rinv
;
182 /* End of tabulated interaction part */
185 /* This is the code you would want instead if not using
189 vc
= qq
*erf(ewc
*dr
)*rinv
;
191 fscal
= rinv2
*(vc
-2.0*qq
*ewc
*isp
*exp(-ewc
*ewc
*dr2
));
194 /* The force vector is obtained by multiplication with the
199 fprintf(debug
,"dr=%8.4f, fscal=%8.0f, df=%10.0f,%10.0f,%10.0f\n",
200 dr
,fscal
,df
[XX
],df
[YY
],df
[ZZ
]);
203 for(iv
=0; (iv
<DIM
); iv
++)
204 for(jv
=0; (jv
<DIM
); jv
++)
205 lr_vir
[iv
][jv
]+=0.5*dx
[iv
]*df
[jv
];
211 fprintf(fp
,"Long Range correction: Vexcl=%g\n",Vexcl
);
215 return (Vself
+Vexcl
);