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