Valgrind suppression for OS X 10.9
[alexxy/gromacs.git] / src / gromacs / gmxlib / nonbonded / nb_kernel_c / nb_kernel_ElecRFCut_VdwLJSw_GeomW4P1_c.c
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2012,2013, by the GROMACS development team, led by
5  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6  * and including many others, as listed in the AUTHORS file in the
7  * top-level source directory and at http://www.gromacs.org.
8  *
9  * GROMACS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1
12  * of the License, or (at your option) any later version.
13  *
14  * GROMACS is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with GROMACS; if not, see
21  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
23  *
24  * If you want to redistribute modifications to GROMACS, please
25  * consider that scientific software is very special. Version
26  * control is crucial - bugs must be traceable. We will be happy to
27  * consider code for inclusion in the official distribution, but
28  * derived work must not be called official GROMACS. Details are found
29  * in the README & COPYING files - if they are missing, get the
30  * official version at http://www.gromacs.org.
31  *
32  * To help us fund GROMACS development, we humbly ask that you cite
33  * the research papers on the package. Check out http://www.gromacs.org.
34  */
35 /*
36  * Note: this file was generated by the GROMACS c kernel generator.
37  */
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif
41
42 #include <math.h>
43
44 #include "../nb_kernel.h"
45 #include "types/simple.h"
46 #include "vec.h"
47 #include "nrnb.h"
48
49 /*
50  * Gromacs nonbonded kernel:   nb_kernel_ElecRFCut_VdwLJSw_GeomW4P1_VF_c
51  * Electrostatics interaction: ReactionField
52  * VdW interaction:            LennardJones
53  * Geometry:                   Water4-Particle
54  * Calculate force/pot:        PotentialAndForce
55  */
56 void
57 nb_kernel_ElecRFCut_VdwLJSw_GeomW4P1_VF_c
58                     (t_nblist                    * gmx_restrict       nlist,
59                      rvec                        * gmx_restrict          xx,
60                      rvec                        * gmx_restrict          ff,
61                      t_forcerec                  * gmx_restrict          fr,
62                      t_mdatoms                   * gmx_restrict     mdatoms,
63                      nb_kernel_data_t gmx_unused * gmx_restrict kernel_data,
64                      t_nrnb                      * gmx_restrict        nrnb)
65 {
66     int              i_shift_offset,i_coord_offset,j_coord_offset;
67     int              j_index_start,j_index_end;
68     int              nri,inr,ggid,iidx,jidx,jnr,outeriter,inneriter;
69     real             shX,shY,shZ,tx,ty,tz,fscal,rcutoff,rcutoff2;
70     int              *iinr,*jindex,*jjnr,*shiftidx,*gid;
71     real             *shiftvec,*fshift,*x,*f;
72     int              vdwioffset0;
73     real             ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
74     int              vdwioffset1;
75     real             ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
76     int              vdwioffset2;
77     real             ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
78     int              vdwioffset3;
79     real             ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
80     int              vdwjidx0;
81     real             jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
82     real             dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00,cexp1_00,cexp2_00;
83     real             dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10,cexp1_10,cexp2_10;
84     real             dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20,cexp1_20,cexp2_20;
85     real             dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30,cexp1_30,cexp2_30;
86     real             velec,felec,velecsum,facel,crf,krf,krf2;
87     real             *charge;
88     int              nvdwtype;
89     real             rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,br,vvdwexp,sh_vdw_invrcut6;
90     int              *vdwtype;
91     real             *vdwparam;
92     real             rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
93
94     x                = xx[0];
95     f                = ff[0];
96
97     nri              = nlist->nri;
98     iinr             = nlist->iinr;
99     jindex           = nlist->jindex;
100     jjnr             = nlist->jjnr;
101     shiftidx         = nlist->shift;
102     gid              = nlist->gid;
103     shiftvec         = fr->shift_vec[0];
104     fshift           = fr->fshift[0];
105     facel            = fr->epsfac;
106     charge           = mdatoms->chargeA;
107     krf              = fr->ic->k_rf;
108     krf2             = krf*2.0;
109     crf              = fr->ic->c_rf;
110     nvdwtype         = fr->ntype;
111     vdwparam         = fr->nbfp;
112     vdwtype          = mdatoms->typeA;
113
114     /* Setup water-specific parameters */
115     inr              = nlist->iinr[0];
116     iq1              = facel*charge[inr+1];
117     iq2              = facel*charge[inr+2];
118     iq3              = facel*charge[inr+3];
119     vdwioffset0      = 2*nvdwtype*vdwtype[inr+0];
120
121     /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
122     rcutoff          = fr->rcoulomb;
123     rcutoff2         = rcutoff*rcutoff;
124
125     rswitch          = fr->rvdw_switch;
126     /* Setup switch parameters */
127     d                = rcutoff-rswitch;
128     swV3             = -10.0/(d*d*d);
129     swV4             =  15.0/(d*d*d*d);
130     swV5             =  -6.0/(d*d*d*d*d);
131     swF2             = -30.0/(d*d*d);
132     swF3             =  60.0/(d*d*d*d);
133     swF4             = -30.0/(d*d*d*d*d);
134
135     outeriter        = 0;
136     inneriter        = 0;
137
138     /* Start outer loop over neighborlists */
139     for(iidx=0; iidx<nri; iidx++)
140     {
141         /* Load shift vector for this list */
142         i_shift_offset   = DIM*shiftidx[iidx];
143         shX              = shiftvec[i_shift_offset+XX];
144         shY              = shiftvec[i_shift_offset+YY];
145         shZ              = shiftvec[i_shift_offset+ZZ];
146
147         /* Load limits for loop over neighbors */
148         j_index_start    = jindex[iidx];
149         j_index_end      = jindex[iidx+1];
150
151         /* Get outer coordinate index */
152         inr              = iinr[iidx];
153         i_coord_offset   = DIM*inr;
154
155         /* Load i particle coords and add shift vector */
156         ix0              = shX + x[i_coord_offset+DIM*0+XX];
157         iy0              = shY + x[i_coord_offset+DIM*0+YY];
158         iz0              = shZ + x[i_coord_offset+DIM*0+ZZ];
159         ix1              = shX + x[i_coord_offset+DIM*1+XX];
160         iy1              = shY + x[i_coord_offset+DIM*1+YY];
161         iz1              = shZ + x[i_coord_offset+DIM*1+ZZ];
162         ix2              = shX + x[i_coord_offset+DIM*2+XX];
163         iy2              = shY + x[i_coord_offset+DIM*2+YY];
164         iz2              = shZ + x[i_coord_offset+DIM*2+ZZ];
165         ix3              = shX + x[i_coord_offset+DIM*3+XX];
166         iy3              = shY + x[i_coord_offset+DIM*3+YY];
167         iz3              = shZ + x[i_coord_offset+DIM*3+ZZ];
168
169         fix0             = 0.0;
170         fiy0             = 0.0;
171         fiz0             = 0.0;
172         fix1             = 0.0;
173         fiy1             = 0.0;
174         fiz1             = 0.0;
175         fix2             = 0.0;
176         fiy2             = 0.0;
177         fiz2             = 0.0;
178         fix3             = 0.0;
179         fiy3             = 0.0;
180         fiz3             = 0.0;
181
182         /* Reset potential sums */
183         velecsum         = 0.0;
184         vvdwsum          = 0.0;
185
186         /* Start inner kernel loop */
187         for(jidx=j_index_start; jidx<j_index_end; jidx++)
188         {
189             /* Get j neighbor index, and coordinate index */
190             jnr              = jjnr[jidx];
191             j_coord_offset   = DIM*jnr;
192
193             /* load j atom coordinates */
194             jx0              = x[j_coord_offset+DIM*0+XX];
195             jy0              = x[j_coord_offset+DIM*0+YY];
196             jz0              = x[j_coord_offset+DIM*0+ZZ];
197
198             /* Calculate displacement vector */
199             dx00             = ix0 - jx0;
200             dy00             = iy0 - jy0;
201             dz00             = iz0 - jz0;
202             dx10             = ix1 - jx0;
203             dy10             = iy1 - jy0;
204             dz10             = iz1 - jz0;
205             dx20             = ix2 - jx0;
206             dy20             = iy2 - jy0;
207             dz20             = iz2 - jz0;
208             dx30             = ix3 - jx0;
209             dy30             = iy3 - jy0;
210             dz30             = iz3 - jz0;
211
212             /* Calculate squared distance and things based on it */
213             rsq00            = dx00*dx00+dy00*dy00+dz00*dz00;
214             rsq10            = dx10*dx10+dy10*dy10+dz10*dz10;
215             rsq20            = dx20*dx20+dy20*dy20+dz20*dz20;
216             rsq30            = dx30*dx30+dy30*dy30+dz30*dz30;
217
218             rinv00           = gmx_invsqrt(rsq00);
219             rinv10           = gmx_invsqrt(rsq10);
220             rinv20           = gmx_invsqrt(rsq20);
221             rinv30           = gmx_invsqrt(rsq30);
222
223             rinvsq00         = rinv00*rinv00;
224             rinvsq10         = rinv10*rinv10;
225             rinvsq20         = rinv20*rinv20;
226             rinvsq30         = rinv30*rinv30;
227
228             /* Load parameters for j particles */
229             jq0              = charge[jnr+0];
230             vdwjidx0         = 2*vdwtype[jnr+0];
231
232             /**************************
233              * CALCULATE INTERACTIONS *
234              **************************/
235
236             if (rsq00<rcutoff2)
237             {
238
239             r00              = rsq00*rinv00;
240
241             c6_00            = vdwparam[vdwioffset0+vdwjidx0];
242             c12_00           = vdwparam[vdwioffset0+vdwjidx0+1];
243
244             /* LENNARD-JONES DISPERSION/REPULSION */
245
246             rinvsix          = rinvsq00*rinvsq00*rinvsq00;
247             vvdw6            = c6_00*rinvsix;
248             vvdw12           = c12_00*rinvsix*rinvsix;
249             vvdw             = vvdw12*(1.0/12.0) - vvdw6*(1.0/6.0);
250             fvdw             = (vvdw12-vvdw6)*rinvsq00;
251
252             d                = r00-rswitch;
253             d                = (d>0.0) ? d : 0.0;
254             d2               = d*d;
255             sw               = 1.0+d2*d*(swV3+d*(swV4+d*swV5));
256
257             dsw              = d2*(swF2+d*(swF3+d*swF4));
258
259             /* Evaluate switch function */
260             /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
261             fvdw             = fvdw*sw - rinv00*vvdw*dsw;
262             vvdw            *= sw;
263
264             /* Update potential sums from outer loop */
265             vvdwsum         += vvdw;
266
267             fscal            = fvdw;
268
269             /* Calculate temporary vectorial force */
270             tx               = fscal*dx00;
271             ty               = fscal*dy00;
272             tz               = fscal*dz00;
273
274             /* Update vectorial force */
275             fix0            += tx;
276             fiy0            += ty;
277             fiz0            += tz;
278             f[j_coord_offset+DIM*0+XX] -= tx;
279             f[j_coord_offset+DIM*0+YY] -= ty;
280             f[j_coord_offset+DIM*0+ZZ] -= tz;
281
282             }
283
284             /**************************
285              * CALCULATE INTERACTIONS *
286              **************************/
287
288             if (rsq10<rcutoff2)
289             {
290
291             qq10             = iq1*jq0;
292
293             /* REACTION-FIELD ELECTROSTATICS */
294             velec            = qq10*(rinv10+krf*rsq10-crf);
295             felec            = qq10*(rinv10*rinvsq10-krf2);
296
297             /* Update potential sums from outer loop */
298             velecsum        += velec;
299
300             fscal            = felec;
301
302             /* Calculate temporary vectorial force */
303             tx               = fscal*dx10;
304             ty               = fscal*dy10;
305             tz               = fscal*dz10;
306
307             /* Update vectorial force */
308             fix1            += tx;
309             fiy1            += ty;
310             fiz1            += tz;
311             f[j_coord_offset+DIM*0+XX] -= tx;
312             f[j_coord_offset+DIM*0+YY] -= ty;
313             f[j_coord_offset+DIM*0+ZZ] -= tz;
314
315             }
316
317             /**************************
318              * CALCULATE INTERACTIONS *
319              **************************/
320
321             if (rsq20<rcutoff2)
322             {
323
324             qq20             = iq2*jq0;
325
326             /* REACTION-FIELD ELECTROSTATICS */
327             velec            = qq20*(rinv20+krf*rsq20-crf);
328             felec            = qq20*(rinv20*rinvsq20-krf2);
329
330             /* Update potential sums from outer loop */
331             velecsum        += velec;
332
333             fscal            = felec;
334
335             /* Calculate temporary vectorial force */
336             tx               = fscal*dx20;
337             ty               = fscal*dy20;
338             tz               = fscal*dz20;
339
340             /* Update vectorial force */
341             fix2            += tx;
342             fiy2            += ty;
343             fiz2            += tz;
344             f[j_coord_offset+DIM*0+XX] -= tx;
345             f[j_coord_offset+DIM*0+YY] -= ty;
346             f[j_coord_offset+DIM*0+ZZ] -= tz;
347
348             }
349
350             /**************************
351              * CALCULATE INTERACTIONS *
352              **************************/
353
354             if (rsq30<rcutoff2)
355             {
356
357             qq30             = iq3*jq0;
358
359             /* REACTION-FIELD ELECTROSTATICS */
360             velec            = qq30*(rinv30+krf*rsq30-crf);
361             felec            = qq30*(rinv30*rinvsq30-krf2);
362
363             /* Update potential sums from outer loop */
364             velecsum        += velec;
365
366             fscal            = felec;
367
368             /* Calculate temporary vectorial force */
369             tx               = fscal*dx30;
370             ty               = fscal*dy30;
371             tz               = fscal*dz30;
372
373             /* Update vectorial force */
374             fix3            += tx;
375             fiy3            += ty;
376             fiz3            += tz;
377             f[j_coord_offset+DIM*0+XX] -= tx;
378             f[j_coord_offset+DIM*0+YY] -= ty;
379             f[j_coord_offset+DIM*0+ZZ] -= tz;
380
381             }
382
383             /* Inner loop uses 149 flops */
384         }
385         /* End of innermost loop */
386
387         tx = ty = tz = 0;
388         f[i_coord_offset+DIM*0+XX] += fix0;
389         f[i_coord_offset+DIM*0+YY] += fiy0;
390         f[i_coord_offset+DIM*0+ZZ] += fiz0;
391         tx                         += fix0;
392         ty                         += fiy0;
393         tz                         += fiz0;
394         f[i_coord_offset+DIM*1+XX] += fix1;
395         f[i_coord_offset+DIM*1+YY] += fiy1;
396         f[i_coord_offset+DIM*1+ZZ] += fiz1;
397         tx                         += fix1;
398         ty                         += fiy1;
399         tz                         += fiz1;
400         f[i_coord_offset+DIM*2+XX] += fix2;
401         f[i_coord_offset+DIM*2+YY] += fiy2;
402         f[i_coord_offset+DIM*2+ZZ] += fiz2;
403         tx                         += fix2;
404         ty                         += fiy2;
405         tz                         += fiz2;
406         f[i_coord_offset+DIM*3+XX] += fix3;
407         f[i_coord_offset+DIM*3+YY] += fiy3;
408         f[i_coord_offset+DIM*3+ZZ] += fiz3;
409         tx                         += fix3;
410         ty                         += fiy3;
411         tz                         += fiz3;
412         fshift[i_shift_offset+XX]  += tx;
413         fshift[i_shift_offset+YY]  += ty;
414         fshift[i_shift_offset+ZZ]  += tz;
415
416         ggid                        = gid[iidx];
417         /* Update potential energies */
418         kernel_data->energygrp_elec[ggid] += velecsum;
419         kernel_data->energygrp_vdw[ggid] += vvdwsum;
420
421         /* Increment number of inner iterations */
422         inneriter                  += j_index_end - j_index_start;
423
424         /* Outer loop uses 41 flops */
425     }
426
427     /* Increment number of outer iterations */
428     outeriter        += nri;
429
430     /* Update outer/inner flops */
431
432     inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4_VF,outeriter*41 + inneriter*149);
433 }
434 /*
435  * Gromacs nonbonded kernel:   nb_kernel_ElecRFCut_VdwLJSw_GeomW4P1_F_c
436  * Electrostatics interaction: ReactionField
437  * VdW interaction:            LennardJones
438  * Geometry:                   Water4-Particle
439  * Calculate force/pot:        Force
440  */
441 void
442 nb_kernel_ElecRFCut_VdwLJSw_GeomW4P1_F_c
443                     (t_nblist                    * gmx_restrict       nlist,
444                      rvec                        * gmx_restrict          xx,
445                      rvec                        * gmx_restrict          ff,
446                      t_forcerec                  * gmx_restrict          fr,
447                      t_mdatoms                   * gmx_restrict     mdatoms,
448                      nb_kernel_data_t gmx_unused * gmx_restrict kernel_data,
449                      t_nrnb                      * gmx_restrict        nrnb)
450 {
451     int              i_shift_offset,i_coord_offset,j_coord_offset;
452     int              j_index_start,j_index_end;
453     int              nri,inr,ggid,iidx,jidx,jnr,outeriter,inneriter;
454     real             shX,shY,shZ,tx,ty,tz,fscal,rcutoff,rcutoff2;
455     int              *iinr,*jindex,*jjnr,*shiftidx,*gid;
456     real             *shiftvec,*fshift,*x,*f;
457     int              vdwioffset0;
458     real             ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
459     int              vdwioffset1;
460     real             ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
461     int              vdwioffset2;
462     real             ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
463     int              vdwioffset3;
464     real             ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
465     int              vdwjidx0;
466     real             jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
467     real             dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00,cexp1_00,cexp2_00;
468     real             dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10,cexp1_10,cexp2_10;
469     real             dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20,cexp1_20,cexp2_20;
470     real             dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30,cexp1_30,cexp2_30;
471     real             velec,felec,velecsum,facel,crf,krf,krf2;
472     real             *charge;
473     int              nvdwtype;
474     real             rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,br,vvdwexp,sh_vdw_invrcut6;
475     int              *vdwtype;
476     real             *vdwparam;
477     real             rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
478
479     x                = xx[0];
480     f                = ff[0];
481
482     nri              = nlist->nri;
483     iinr             = nlist->iinr;
484     jindex           = nlist->jindex;
485     jjnr             = nlist->jjnr;
486     shiftidx         = nlist->shift;
487     gid              = nlist->gid;
488     shiftvec         = fr->shift_vec[0];
489     fshift           = fr->fshift[0];
490     facel            = fr->epsfac;
491     charge           = mdatoms->chargeA;
492     krf              = fr->ic->k_rf;
493     krf2             = krf*2.0;
494     crf              = fr->ic->c_rf;
495     nvdwtype         = fr->ntype;
496     vdwparam         = fr->nbfp;
497     vdwtype          = mdatoms->typeA;
498
499     /* Setup water-specific parameters */
500     inr              = nlist->iinr[0];
501     iq1              = facel*charge[inr+1];
502     iq2              = facel*charge[inr+2];
503     iq3              = facel*charge[inr+3];
504     vdwioffset0      = 2*nvdwtype*vdwtype[inr+0];
505
506     /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
507     rcutoff          = fr->rcoulomb;
508     rcutoff2         = rcutoff*rcutoff;
509
510     rswitch          = fr->rvdw_switch;
511     /* Setup switch parameters */
512     d                = rcutoff-rswitch;
513     swV3             = -10.0/(d*d*d);
514     swV4             =  15.0/(d*d*d*d);
515     swV5             =  -6.0/(d*d*d*d*d);
516     swF2             = -30.0/(d*d*d);
517     swF3             =  60.0/(d*d*d*d);
518     swF4             = -30.0/(d*d*d*d*d);
519
520     outeriter        = 0;
521     inneriter        = 0;
522
523     /* Start outer loop over neighborlists */
524     for(iidx=0; iidx<nri; iidx++)
525     {
526         /* Load shift vector for this list */
527         i_shift_offset   = DIM*shiftidx[iidx];
528         shX              = shiftvec[i_shift_offset+XX];
529         shY              = shiftvec[i_shift_offset+YY];
530         shZ              = shiftvec[i_shift_offset+ZZ];
531
532         /* Load limits for loop over neighbors */
533         j_index_start    = jindex[iidx];
534         j_index_end      = jindex[iidx+1];
535
536         /* Get outer coordinate index */
537         inr              = iinr[iidx];
538         i_coord_offset   = DIM*inr;
539
540         /* Load i particle coords and add shift vector */
541         ix0              = shX + x[i_coord_offset+DIM*0+XX];
542         iy0              = shY + x[i_coord_offset+DIM*0+YY];
543         iz0              = shZ + x[i_coord_offset+DIM*0+ZZ];
544         ix1              = shX + x[i_coord_offset+DIM*1+XX];
545         iy1              = shY + x[i_coord_offset+DIM*1+YY];
546         iz1              = shZ + x[i_coord_offset+DIM*1+ZZ];
547         ix2              = shX + x[i_coord_offset+DIM*2+XX];
548         iy2              = shY + x[i_coord_offset+DIM*2+YY];
549         iz2              = shZ + x[i_coord_offset+DIM*2+ZZ];
550         ix3              = shX + x[i_coord_offset+DIM*3+XX];
551         iy3              = shY + x[i_coord_offset+DIM*3+YY];
552         iz3              = shZ + x[i_coord_offset+DIM*3+ZZ];
553
554         fix0             = 0.0;
555         fiy0             = 0.0;
556         fiz0             = 0.0;
557         fix1             = 0.0;
558         fiy1             = 0.0;
559         fiz1             = 0.0;
560         fix2             = 0.0;
561         fiy2             = 0.0;
562         fiz2             = 0.0;
563         fix3             = 0.0;
564         fiy3             = 0.0;
565         fiz3             = 0.0;
566
567         /* Start inner kernel loop */
568         for(jidx=j_index_start; jidx<j_index_end; jidx++)
569         {
570             /* Get j neighbor index, and coordinate index */
571             jnr              = jjnr[jidx];
572             j_coord_offset   = DIM*jnr;
573
574             /* load j atom coordinates */
575             jx0              = x[j_coord_offset+DIM*0+XX];
576             jy0              = x[j_coord_offset+DIM*0+YY];
577             jz0              = x[j_coord_offset+DIM*0+ZZ];
578
579             /* Calculate displacement vector */
580             dx00             = ix0 - jx0;
581             dy00             = iy0 - jy0;
582             dz00             = iz0 - jz0;
583             dx10             = ix1 - jx0;
584             dy10             = iy1 - jy0;
585             dz10             = iz1 - jz0;
586             dx20             = ix2 - jx0;
587             dy20             = iy2 - jy0;
588             dz20             = iz2 - jz0;
589             dx30             = ix3 - jx0;
590             dy30             = iy3 - jy0;
591             dz30             = iz3 - jz0;
592
593             /* Calculate squared distance and things based on it */
594             rsq00            = dx00*dx00+dy00*dy00+dz00*dz00;
595             rsq10            = dx10*dx10+dy10*dy10+dz10*dz10;
596             rsq20            = dx20*dx20+dy20*dy20+dz20*dz20;
597             rsq30            = dx30*dx30+dy30*dy30+dz30*dz30;
598
599             rinv00           = gmx_invsqrt(rsq00);
600             rinv10           = gmx_invsqrt(rsq10);
601             rinv20           = gmx_invsqrt(rsq20);
602             rinv30           = gmx_invsqrt(rsq30);
603
604             rinvsq00         = rinv00*rinv00;
605             rinvsq10         = rinv10*rinv10;
606             rinvsq20         = rinv20*rinv20;
607             rinvsq30         = rinv30*rinv30;
608
609             /* Load parameters for j particles */
610             jq0              = charge[jnr+0];
611             vdwjidx0         = 2*vdwtype[jnr+0];
612
613             /**************************
614              * CALCULATE INTERACTIONS *
615              **************************/
616
617             if (rsq00<rcutoff2)
618             {
619
620             r00              = rsq00*rinv00;
621
622             c6_00            = vdwparam[vdwioffset0+vdwjidx0];
623             c12_00           = vdwparam[vdwioffset0+vdwjidx0+1];
624
625             /* LENNARD-JONES DISPERSION/REPULSION */
626
627             rinvsix          = rinvsq00*rinvsq00*rinvsq00;
628             vvdw6            = c6_00*rinvsix;
629             vvdw12           = c12_00*rinvsix*rinvsix;
630             vvdw             = vvdw12*(1.0/12.0) - vvdw6*(1.0/6.0);
631             fvdw             = (vvdw12-vvdw6)*rinvsq00;
632
633             d                = r00-rswitch;
634             d                = (d>0.0) ? d : 0.0;
635             d2               = d*d;
636             sw               = 1.0+d2*d*(swV3+d*(swV4+d*swV5));
637
638             dsw              = d2*(swF2+d*(swF3+d*swF4));
639
640             /* Evaluate switch function */
641             /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
642             fvdw             = fvdw*sw - rinv00*vvdw*dsw;
643
644             fscal            = fvdw;
645
646             /* Calculate temporary vectorial force */
647             tx               = fscal*dx00;
648             ty               = fscal*dy00;
649             tz               = fscal*dz00;
650
651             /* Update vectorial force */
652             fix0            += tx;
653             fiy0            += ty;
654             fiz0            += tz;
655             f[j_coord_offset+DIM*0+XX] -= tx;
656             f[j_coord_offset+DIM*0+YY] -= ty;
657             f[j_coord_offset+DIM*0+ZZ] -= tz;
658
659             }
660
661             /**************************
662              * CALCULATE INTERACTIONS *
663              **************************/
664
665             if (rsq10<rcutoff2)
666             {
667
668             qq10             = iq1*jq0;
669
670             /* REACTION-FIELD ELECTROSTATICS */
671             felec            = qq10*(rinv10*rinvsq10-krf2);
672
673             fscal            = felec;
674
675             /* Calculate temporary vectorial force */
676             tx               = fscal*dx10;
677             ty               = fscal*dy10;
678             tz               = fscal*dz10;
679
680             /* Update vectorial force */
681             fix1            += tx;
682             fiy1            += ty;
683             fiz1            += tz;
684             f[j_coord_offset+DIM*0+XX] -= tx;
685             f[j_coord_offset+DIM*0+YY] -= ty;
686             f[j_coord_offset+DIM*0+ZZ] -= tz;
687
688             }
689
690             /**************************
691              * CALCULATE INTERACTIONS *
692              **************************/
693
694             if (rsq20<rcutoff2)
695             {
696
697             qq20             = iq2*jq0;
698
699             /* REACTION-FIELD ELECTROSTATICS */
700             felec            = qq20*(rinv20*rinvsq20-krf2);
701
702             fscal            = felec;
703
704             /* Calculate temporary vectorial force */
705             tx               = fscal*dx20;
706             ty               = fscal*dy20;
707             tz               = fscal*dz20;
708
709             /* Update vectorial force */
710             fix2            += tx;
711             fiy2            += ty;
712             fiz2            += tz;
713             f[j_coord_offset+DIM*0+XX] -= tx;
714             f[j_coord_offset+DIM*0+YY] -= ty;
715             f[j_coord_offset+DIM*0+ZZ] -= tz;
716
717             }
718
719             /**************************
720              * CALCULATE INTERACTIONS *
721              **************************/
722
723             if (rsq30<rcutoff2)
724             {
725
726             qq30             = iq3*jq0;
727
728             /* REACTION-FIELD ELECTROSTATICS */
729             felec            = qq30*(rinv30*rinvsq30-krf2);
730
731             fscal            = felec;
732
733             /* Calculate temporary vectorial force */
734             tx               = fscal*dx30;
735             ty               = fscal*dy30;
736             tz               = fscal*dz30;
737
738             /* Update vectorial force */
739             fix3            += tx;
740             fiy3            += ty;
741             fiz3            += tz;
742             f[j_coord_offset+DIM*0+XX] -= tx;
743             f[j_coord_offset+DIM*0+YY] -= ty;
744             f[j_coord_offset+DIM*0+ZZ] -= tz;
745
746             }
747
748             /* Inner loop uses 132 flops */
749         }
750         /* End of innermost loop */
751
752         tx = ty = tz = 0;
753         f[i_coord_offset+DIM*0+XX] += fix0;
754         f[i_coord_offset+DIM*0+YY] += fiy0;
755         f[i_coord_offset+DIM*0+ZZ] += fiz0;
756         tx                         += fix0;
757         ty                         += fiy0;
758         tz                         += fiz0;
759         f[i_coord_offset+DIM*1+XX] += fix1;
760         f[i_coord_offset+DIM*1+YY] += fiy1;
761         f[i_coord_offset+DIM*1+ZZ] += fiz1;
762         tx                         += fix1;
763         ty                         += fiy1;
764         tz                         += fiz1;
765         f[i_coord_offset+DIM*2+XX] += fix2;
766         f[i_coord_offset+DIM*2+YY] += fiy2;
767         f[i_coord_offset+DIM*2+ZZ] += fiz2;
768         tx                         += fix2;
769         ty                         += fiy2;
770         tz                         += fiz2;
771         f[i_coord_offset+DIM*3+XX] += fix3;
772         f[i_coord_offset+DIM*3+YY] += fiy3;
773         f[i_coord_offset+DIM*3+ZZ] += fiz3;
774         tx                         += fix3;
775         ty                         += fiy3;
776         tz                         += fiz3;
777         fshift[i_shift_offset+XX]  += tx;
778         fshift[i_shift_offset+YY]  += ty;
779         fshift[i_shift_offset+ZZ]  += tz;
780
781         /* Increment number of inner iterations */
782         inneriter                  += j_index_end - j_index_start;
783
784         /* Outer loop uses 39 flops */
785     }
786
787     /* Increment number of outer iterations */
788     outeriter        += nri;
789
790     /* Update outer/inner flops */
791
792     inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4_F,outeriter*39 + inneriter*132);
793 }