a56a0f66a8e2567e5653cf039a251d99c674d34b
[alexxy/gromacs.git] / src / gromacs / gmxlib / nonbonded / nb_kernel_c / nb_kernel_ElecRFCut_VdwLJSh_GeomW4P1_c.c
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2012,2013,2014, 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 #include "config.h"
39
40 #include <math.h>
41
42 #include "../nb_kernel.h"
43 #include "gromacs/legacyheaders/types/simple.h"
44 #include "gromacs/math/vec.h"
45 #include "gromacs/legacyheaders/nrnb.h"
46
47 /*
48  * Gromacs nonbonded kernel:   nb_kernel_ElecRFCut_VdwLJSh_GeomW4P1_VF_c
49  * Electrostatics interaction: ReactionField
50  * VdW interaction:            LennardJones
51  * Geometry:                   Water4-Particle
52  * Calculate force/pot:        PotentialAndForce
53  */
54 void
55 nb_kernel_ElecRFCut_VdwLJSh_GeomW4P1_VF_c
56                     (t_nblist                    * gmx_restrict       nlist,
57                      rvec                        * gmx_restrict          xx,
58                      rvec                        * gmx_restrict          ff,
59                      t_forcerec                  * gmx_restrict          fr,
60                      t_mdatoms                   * gmx_restrict     mdatoms,
61                      nb_kernel_data_t gmx_unused * gmx_restrict kernel_data,
62                      t_nrnb                      * gmx_restrict        nrnb)
63 {
64     int              i_shift_offset,i_coord_offset,j_coord_offset;
65     int              j_index_start,j_index_end;
66     int              nri,inr,ggid,iidx,jidx,jnr,outeriter,inneriter;
67     real             shX,shY,shZ,tx,ty,tz,fscal,rcutoff,rcutoff2;
68     int              *iinr,*jindex,*jjnr,*shiftidx,*gid;
69     real             *shiftvec,*fshift,*x,*f;
70     int              vdwioffset0;
71     real             ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
72     int              vdwioffset1;
73     real             ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
74     int              vdwioffset2;
75     real             ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
76     int              vdwioffset3;
77     real             ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
78     int              vdwjidx0;
79     real             jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
80     real             dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00,cexp1_00,cexp2_00;
81     real             dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10,cexp1_10,cexp2_10;
82     real             dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20,cexp1_20,cexp2_20;
83     real             dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30,cexp1_30,cexp2_30;
84     real             velec,felec,velecsum,facel,crf,krf,krf2;
85     real             *charge;
86     int              nvdwtype;
87     real             rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,br,vvdwexp,sh_vdw_invrcut6;
88     int              *vdwtype;
89     real             *vdwparam;
90
91     x                = xx[0];
92     f                = ff[0];
93
94     nri              = nlist->nri;
95     iinr             = nlist->iinr;
96     jindex           = nlist->jindex;
97     jjnr             = nlist->jjnr;
98     shiftidx         = nlist->shift;
99     gid              = nlist->gid;
100     shiftvec         = fr->shift_vec[0];
101     fshift           = fr->fshift[0];
102     facel            = fr->epsfac;
103     charge           = mdatoms->chargeA;
104     krf              = fr->ic->k_rf;
105     krf2             = krf*2.0;
106     crf              = fr->ic->c_rf;
107     nvdwtype         = fr->ntype;
108     vdwparam         = fr->nbfp;
109     vdwtype          = mdatoms->typeA;
110
111     /* Setup water-specific parameters */
112     inr              = nlist->iinr[0];
113     iq1              = facel*charge[inr+1];
114     iq2              = facel*charge[inr+2];
115     iq3              = facel*charge[inr+3];
116     vdwioffset0      = 2*nvdwtype*vdwtype[inr+0];
117
118     /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
119     rcutoff          = fr->rcoulomb;
120     rcutoff2         = rcutoff*rcutoff;
121
122     sh_vdw_invrcut6  = fr->ic->sh_invrc6;
123     rvdw             = fr->rvdw;
124
125     outeriter        = 0;
126     inneriter        = 0;
127
128     /* Start outer loop over neighborlists */
129     for(iidx=0; iidx<nri; iidx++)
130     {
131         /* Load shift vector for this list */
132         i_shift_offset   = DIM*shiftidx[iidx];
133         shX              = shiftvec[i_shift_offset+XX];
134         shY              = shiftvec[i_shift_offset+YY];
135         shZ              = shiftvec[i_shift_offset+ZZ];
136
137         /* Load limits for loop over neighbors */
138         j_index_start    = jindex[iidx];
139         j_index_end      = jindex[iidx+1];
140
141         /* Get outer coordinate index */
142         inr              = iinr[iidx];
143         i_coord_offset   = DIM*inr;
144
145         /* Load i particle coords and add shift vector */
146         ix0              = shX + x[i_coord_offset+DIM*0+XX];
147         iy0              = shY + x[i_coord_offset+DIM*0+YY];
148         iz0              = shZ + x[i_coord_offset+DIM*0+ZZ];
149         ix1              = shX + x[i_coord_offset+DIM*1+XX];
150         iy1              = shY + x[i_coord_offset+DIM*1+YY];
151         iz1              = shZ + x[i_coord_offset+DIM*1+ZZ];
152         ix2              = shX + x[i_coord_offset+DIM*2+XX];
153         iy2              = shY + x[i_coord_offset+DIM*2+YY];
154         iz2              = shZ + x[i_coord_offset+DIM*2+ZZ];
155         ix3              = shX + x[i_coord_offset+DIM*3+XX];
156         iy3              = shY + x[i_coord_offset+DIM*3+YY];
157         iz3              = shZ + x[i_coord_offset+DIM*3+ZZ];
158
159         fix0             = 0.0;
160         fiy0             = 0.0;
161         fiz0             = 0.0;
162         fix1             = 0.0;
163         fiy1             = 0.0;
164         fiz1             = 0.0;
165         fix2             = 0.0;
166         fiy2             = 0.0;
167         fiz2             = 0.0;
168         fix3             = 0.0;
169         fiy3             = 0.0;
170         fiz3             = 0.0;
171
172         /* Reset potential sums */
173         velecsum         = 0.0;
174         vvdwsum          = 0.0;
175
176         /* Start inner kernel loop */
177         for(jidx=j_index_start; jidx<j_index_end; jidx++)
178         {
179             /* Get j neighbor index, and coordinate index */
180             jnr              = jjnr[jidx];
181             j_coord_offset   = DIM*jnr;
182
183             /* load j atom coordinates */
184             jx0              = x[j_coord_offset+DIM*0+XX];
185             jy0              = x[j_coord_offset+DIM*0+YY];
186             jz0              = x[j_coord_offset+DIM*0+ZZ];
187
188             /* Calculate displacement vector */
189             dx00             = ix0 - jx0;
190             dy00             = iy0 - jy0;
191             dz00             = iz0 - jz0;
192             dx10             = ix1 - jx0;
193             dy10             = iy1 - jy0;
194             dz10             = iz1 - jz0;
195             dx20             = ix2 - jx0;
196             dy20             = iy2 - jy0;
197             dz20             = iz2 - jz0;
198             dx30             = ix3 - jx0;
199             dy30             = iy3 - jy0;
200             dz30             = iz3 - jz0;
201
202             /* Calculate squared distance and things based on it */
203             rsq00            = dx00*dx00+dy00*dy00+dz00*dz00;
204             rsq10            = dx10*dx10+dy10*dy10+dz10*dz10;
205             rsq20            = dx20*dx20+dy20*dy20+dz20*dz20;
206             rsq30            = dx30*dx30+dy30*dy30+dz30*dz30;
207
208             rinv10           = gmx_invsqrt(rsq10);
209             rinv20           = gmx_invsqrt(rsq20);
210             rinv30           = gmx_invsqrt(rsq30);
211
212             rinvsq00         = 1.0/rsq00;
213             rinvsq10         = rinv10*rinv10;
214             rinvsq20         = rinv20*rinv20;
215             rinvsq30         = rinv30*rinv30;
216
217             /* Load parameters for j particles */
218             jq0              = charge[jnr+0];
219             vdwjidx0         = 2*vdwtype[jnr+0];
220
221             /**************************
222              * CALCULATE INTERACTIONS *
223              **************************/
224
225             if (rsq00<rcutoff2)
226             {
227
228             c6_00            = vdwparam[vdwioffset0+vdwjidx0];
229             c12_00           = vdwparam[vdwioffset0+vdwjidx0+1];
230
231             /* LENNARD-JONES DISPERSION/REPULSION */
232
233             rinvsix          = rinvsq00*rinvsq00*rinvsq00;
234             vvdw6            = c6_00*rinvsix;
235             vvdw12           = c12_00*rinvsix*rinvsix;
236             vvdw             = (vvdw12 - c12_00*sh_vdw_invrcut6*sh_vdw_invrcut6)*(1.0/12.0) - (vvdw6 - c6_00*sh_vdw_invrcut6)*(1.0/6.0);
237             fvdw             = (vvdw12-vvdw6)*rinvsq00;
238
239             /* Update potential sums from outer loop */
240             vvdwsum         += vvdw;
241
242             fscal            = fvdw;
243
244             /* Calculate temporary vectorial force */
245             tx               = fscal*dx00;
246             ty               = fscal*dy00;
247             tz               = fscal*dz00;
248
249             /* Update vectorial force */
250             fix0            += tx;
251             fiy0            += ty;
252             fiz0            += tz;
253             f[j_coord_offset+DIM*0+XX] -= tx;
254             f[j_coord_offset+DIM*0+YY] -= ty;
255             f[j_coord_offset+DIM*0+ZZ] -= tz;
256
257             }
258
259             /**************************
260              * CALCULATE INTERACTIONS *
261              **************************/
262
263             if (rsq10<rcutoff2)
264             {
265
266             qq10             = iq1*jq0;
267
268             /* REACTION-FIELD ELECTROSTATICS */
269             velec            = qq10*(rinv10+krf*rsq10-crf);
270             felec            = qq10*(rinv10*rinvsq10-krf2);
271
272             /* Update potential sums from outer loop */
273             velecsum        += velec;
274
275             fscal            = felec;
276
277             /* Calculate temporary vectorial force */
278             tx               = fscal*dx10;
279             ty               = fscal*dy10;
280             tz               = fscal*dz10;
281
282             /* Update vectorial force */
283             fix1            += tx;
284             fiy1            += ty;
285             fiz1            += tz;
286             f[j_coord_offset+DIM*0+XX] -= tx;
287             f[j_coord_offset+DIM*0+YY] -= ty;
288             f[j_coord_offset+DIM*0+ZZ] -= tz;
289
290             }
291
292             /**************************
293              * CALCULATE INTERACTIONS *
294              **************************/
295
296             if (rsq20<rcutoff2)
297             {
298
299             qq20             = iq2*jq0;
300
301             /* REACTION-FIELD ELECTROSTATICS */
302             velec            = qq20*(rinv20+krf*rsq20-crf);
303             felec            = qq20*(rinv20*rinvsq20-krf2);
304
305             /* Update potential sums from outer loop */
306             velecsum        += velec;
307
308             fscal            = felec;
309
310             /* Calculate temporary vectorial force */
311             tx               = fscal*dx20;
312             ty               = fscal*dy20;
313             tz               = fscal*dz20;
314
315             /* Update vectorial force */
316             fix2            += tx;
317             fiy2            += ty;
318             fiz2            += tz;
319             f[j_coord_offset+DIM*0+XX] -= tx;
320             f[j_coord_offset+DIM*0+YY] -= ty;
321             f[j_coord_offset+DIM*0+ZZ] -= tz;
322
323             }
324
325             /**************************
326              * CALCULATE INTERACTIONS *
327              **************************/
328
329             if (rsq30<rcutoff2)
330             {
331
332             qq30             = iq3*jq0;
333
334             /* REACTION-FIELD ELECTROSTATICS */
335             velec            = qq30*(rinv30+krf*rsq30-crf);
336             felec            = qq30*(rinv30*rinvsq30-krf2);
337
338             /* Update potential sums from outer loop */
339             velecsum        += velec;
340
341             fscal            = felec;
342
343             /* Calculate temporary vectorial force */
344             tx               = fscal*dx30;
345             ty               = fscal*dy30;
346             tz               = fscal*dz30;
347
348             /* Update vectorial force */
349             fix3            += tx;
350             fiy3            += ty;
351             fiz3            += tz;
352             f[j_coord_offset+DIM*0+XX] -= tx;
353             f[j_coord_offset+DIM*0+YY] -= ty;
354             f[j_coord_offset+DIM*0+ZZ] -= tz;
355
356             }
357
358             /* Inner loop uses 133 flops */
359         }
360         /* End of innermost loop */
361
362         tx = ty = tz = 0;
363         f[i_coord_offset+DIM*0+XX] += fix0;
364         f[i_coord_offset+DIM*0+YY] += fiy0;
365         f[i_coord_offset+DIM*0+ZZ] += fiz0;
366         tx                         += fix0;
367         ty                         += fiy0;
368         tz                         += fiz0;
369         f[i_coord_offset+DIM*1+XX] += fix1;
370         f[i_coord_offset+DIM*1+YY] += fiy1;
371         f[i_coord_offset+DIM*1+ZZ] += fiz1;
372         tx                         += fix1;
373         ty                         += fiy1;
374         tz                         += fiz1;
375         f[i_coord_offset+DIM*2+XX] += fix2;
376         f[i_coord_offset+DIM*2+YY] += fiy2;
377         f[i_coord_offset+DIM*2+ZZ] += fiz2;
378         tx                         += fix2;
379         ty                         += fiy2;
380         tz                         += fiz2;
381         f[i_coord_offset+DIM*3+XX] += fix3;
382         f[i_coord_offset+DIM*3+YY] += fiy3;
383         f[i_coord_offset+DIM*3+ZZ] += fiz3;
384         tx                         += fix3;
385         ty                         += fiy3;
386         tz                         += fiz3;
387         fshift[i_shift_offset+XX]  += tx;
388         fshift[i_shift_offset+YY]  += ty;
389         fshift[i_shift_offset+ZZ]  += tz;
390
391         ggid                        = gid[iidx];
392         /* Update potential energies */
393         kernel_data->energygrp_elec[ggid] += velecsum;
394         kernel_data->energygrp_vdw[ggid] += vvdwsum;
395
396         /* Increment number of inner iterations */
397         inneriter                  += j_index_end - j_index_start;
398
399         /* Outer loop uses 41 flops */
400     }
401
402     /* Increment number of outer iterations */
403     outeriter        += nri;
404
405     /* Update outer/inner flops */
406
407     inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4_VF,outeriter*41 + inneriter*133);
408 }
409 /*
410  * Gromacs nonbonded kernel:   nb_kernel_ElecRFCut_VdwLJSh_GeomW4P1_F_c
411  * Electrostatics interaction: ReactionField
412  * VdW interaction:            LennardJones
413  * Geometry:                   Water4-Particle
414  * Calculate force/pot:        Force
415  */
416 void
417 nb_kernel_ElecRFCut_VdwLJSh_GeomW4P1_F_c
418                     (t_nblist                    * gmx_restrict       nlist,
419                      rvec                        * gmx_restrict          xx,
420                      rvec                        * gmx_restrict          ff,
421                      t_forcerec                  * gmx_restrict          fr,
422                      t_mdatoms                   * gmx_restrict     mdatoms,
423                      nb_kernel_data_t gmx_unused * gmx_restrict kernel_data,
424                      t_nrnb                      * gmx_restrict        nrnb)
425 {
426     int              i_shift_offset,i_coord_offset,j_coord_offset;
427     int              j_index_start,j_index_end;
428     int              nri,inr,ggid,iidx,jidx,jnr,outeriter,inneriter;
429     real             shX,shY,shZ,tx,ty,tz,fscal,rcutoff,rcutoff2;
430     int              *iinr,*jindex,*jjnr,*shiftidx,*gid;
431     real             *shiftvec,*fshift,*x,*f;
432     int              vdwioffset0;
433     real             ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
434     int              vdwioffset1;
435     real             ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
436     int              vdwioffset2;
437     real             ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
438     int              vdwioffset3;
439     real             ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
440     int              vdwjidx0;
441     real             jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
442     real             dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00,cexp1_00,cexp2_00;
443     real             dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10,cexp1_10,cexp2_10;
444     real             dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20,cexp1_20,cexp2_20;
445     real             dx30,dy30,dz30,rsq30,rinv30,rinvsq30,r30,qq30,c6_30,c12_30,cexp1_30,cexp2_30;
446     real             velec,felec,velecsum,facel,crf,krf,krf2;
447     real             *charge;
448     int              nvdwtype;
449     real             rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,br,vvdwexp,sh_vdw_invrcut6;
450     int              *vdwtype;
451     real             *vdwparam;
452
453     x                = xx[0];
454     f                = ff[0];
455
456     nri              = nlist->nri;
457     iinr             = nlist->iinr;
458     jindex           = nlist->jindex;
459     jjnr             = nlist->jjnr;
460     shiftidx         = nlist->shift;
461     gid              = nlist->gid;
462     shiftvec         = fr->shift_vec[0];
463     fshift           = fr->fshift[0];
464     facel            = fr->epsfac;
465     charge           = mdatoms->chargeA;
466     krf              = fr->ic->k_rf;
467     krf2             = krf*2.0;
468     crf              = fr->ic->c_rf;
469     nvdwtype         = fr->ntype;
470     vdwparam         = fr->nbfp;
471     vdwtype          = mdatoms->typeA;
472
473     /* Setup water-specific parameters */
474     inr              = nlist->iinr[0];
475     iq1              = facel*charge[inr+1];
476     iq2              = facel*charge[inr+2];
477     iq3              = facel*charge[inr+3];
478     vdwioffset0      = 2*nvdwtype*vdwtype[inr+0];
479
480     /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
481     rcutoff          = fr->rcoulomb;
482     rcutoff2         = rcutoff*rcutoff;
483
484     sh_vdw_invrcut6  = fr->ic->sh_invrc6;
485     rvdw             = fr->rvdw;
486
487     outeriter        = 0;
488     inneriter        = 0;
489
490     /* Start outer loop over neighborlists */
491     for(iidx=0; iidx<nri; iidx++)
492     {
493         /* Load shift vector for this list */
494         i_shift_offset   = DIM*shiftidx[iidx];
495         shX              = shiftvec[i_shift_offset+XX];
496         shY              = shiftvec[i_shift_offset+YY];
497         shZ              = shiftvec[i_shift_offset+ZZ];
498
499         /* Load limits for loop over neighbors */
500         j_index_start    = jindex[iidx];
501         j_index_end      = jindex[iidx+1];
502
503         /* Get outer coordinate index */
504         inr              = iinr[iidx];
505         i_coord_offset   = DIM*inr;
506
507         /* Load i particle coords and add shift vector */
508         ix0              = shX + x[i_coord_offset+DIM*0+XX];
509         iy0              = shY + x[i_coord_offset+DIM*0+YY];
510         iz0              = shZ + x[i_coord_offset+DIM*0+ZZ];
511         ix1              = shX + x[i_coord_offset+DIM*1+XX];
512         iy1              = shY + x[i_coord_offset+DIM*1+YY];
513         iz1              = shZ + x[i_coord_offset+DIM*1+ZZ];
514         ix2              = shX + x[i_coord_offset+DIM*2+XX];
515         iy2              = shY + x[i_coord_offset+DIM*2+YY];
516         iz2              = shZ + x[i_coord_offset+DIM*2+ZZ];
517         ix3              = shX + x[i_coord_offset+DIM*3+XX];
518         iy3              = shY + x[i_coord_offset+DIM*3+YY];
519         iz3              = shZ + x[i_coord_offset+DIM*3+ZZ];
520
521         fix0             = 0.0;
522         fiy0             = 0.0;
523         fiz0             = 0.0;
524         fix1             = 0.0;
525         fiy1             = 0.0;
526         fiz1             = 0.0;
527         fix2             = 0.0;
528         fiy2             = 0.0;
529         fiz2             = 0.0;
530         fix3             = 0.0;
531         fiy3             = 0.0;
532         fiz3             = 0.0;
533
534         /* Start inner kernel loop */
535         for(jidx=j_index_start; jidx<j_index_end; jidx++)
536         {
537             /* Get j neighbor index, and coordinate index */
538             jnr              = jjnr[jidx];
539             j_coord_offset   = DIM*jnr;
540
541             /* load j atom coordinates */
542             jx0              = x[j_coord_offset+DIM*0+XX];
543             jy0              = x[j_coord_offset+DIM*0+YY];
544             jz0              = x[j_coord_offset+DIM*0+ZZ];
545
546             /* Calculate displacement vector */
547             dx00             = ix0 - jx0;
548             dy00             = iy0 - jy0;
549             dz00             = iz0 - jz0;
550             dx10             = ix1 - jx0;
551             dy10             = iy1 - jy0;
552             dz10             = iz1 - jz0;
553             dx20             = ix2 - jx0;
554             dy20             = iy2 - jy0;
555             dz20             = iz2 - jz0;
556             dx30             = ix3 - jx0;
557             dy30             = iy3 - jy0;
558             dz30             = iz3 - jz0;
559
560             /* Calculate squared distance and things based on it */
561             rsq00            = dx00*dx00+dy00*dy00+dz00*dz00;
562             rsq10            = dx10*dx10+dy10*dy10+dz10*dz10;
563             rsq20            = dx20*dx20+dy20*dy20+dz20*dz20;
564             rsq30            = dx30*dx30+dy30*dy30+dz30*dz30;
565
566             rinv10           = gmx_invsqrt(rsq10);
567             rinv20           = gmx_invsqrt(rsq20);
568             rinv30           = gmx_invsqrt(rsq30);
569
570             rinvsq00         = 1.0/rsq00;
571             rinvsq10         = rinv10*rinv10;
572             rinvsq20         = rinv20*rinv20;
573             rinvsq30         = rinv30*rinv30;
574
575             /* Load parameters for j particles */
576             jq0              = charge[jnr+0];
577             vdwjidx0         = 2*vdwtype[jnr+0];
578
579             /**************************
580              * CALCULATE INTERACTIONS *
581              **************************/
582
583             if (rsq00<rcutoff2)
584             {
585
586             c6_00            = vdwparam[vdwioffset0+vdwjidx0];
587             c12_00           = vdwparam[vdwioffset0+vdwjidx0+1];
588
589             /* LENNARD-JONES DISPERSION/REPULSION */
590
591             rinvsix          = rinvsq00*rinvsq00*rinvsq00;
592             fvdw             = (c12_00*rinvsix-c6_00)*rinvsix*rinvsq00;
593
594             fscal            = fvdw;
595
596             /* Calculate temporary vectorial force */
597             tx               = fscal*dx00;
598             ty               = fscal*dy00;
599             tz               = fscal*dz00;
600
601             /* Update vectorial force */
602             fix0            += tx;
603             fiy0            += ty;
604             fiz0            += tz;
605             f[j_coord_offset+DIM*0+XX] -= tx;
606             f[j_coord_offset+DIM*0+YY] -= ty;
607             f[j_coord_offset+DIM*0+ZZ] -= tz;
608
609             }
610
611             /**************************
612              * CALCULATE INTERACTIONS *
613              **************************/
614
615             if (rsq10<rcutoff2)
616             {
617
618             qq10             = iq1*jq0;
619
620             /* REACTION-FIELD ELECTROSTATICS */
621             felec            = qq10*(rinv10*rinvsq10-krf2);
622
623             fscal            = felec;
624
625             /* Calculate temporary vectorial force */
626             tx               = fscal*dx10;
627             ty               = fscal*dy10;
628             tz               = fscal*dz10;
629
630             /* Update vectorial force */
631             fix1            += tx;
632             fiy1            += ty;
633             fiz1            += tz;
634             f[j_coord_offset+DIM*0+XX] -= tx;
635             f[j_coord_offset+DIM*0+YY] -= ty;
636             f[j_coord_offset+DIM*0+ZZ] -= tz;
637
638             }
639
640             /**************************
641              * CALCULATE INTERACTIONS *
642              **************************/
643
644             if (rsq20<rcutoff2)
645             {
646
647             qq20             = iq2*jq0;
648
649             /* REACTION-FIELD ELECTROSTATICS */
650             felec            = qq20*(rinv20*rinvsq20-krf2);
651
652             fscal            = felec;
653
654             /* Calculate temporary vectorial force */
655             tx               = fscal*dx20;
656             ty               = fscal*dy20;
657             tz               = fscal*dz20;
658
659             /* Update vectorial force */
660             fix2            += tx;
661             fiy2            += ty;
662             fiz2            += tz;
663             f[j_coord_offset+DIM*0+XX] -= tx;
664             f[j_coord_offset+DIM*0+YY] -= ty;
665             f[j_coord_offset+DIM*0+ZZ] -= tz;
666
667             }
668
669             /**************************
670              * CALCULATE INTERACTIONS *
671              **************************/
672
673             if (rsq30<rcutoff2)
674             {
675
676             qq30             = iq3*jq0;
677
678             /* REACTION-FIELD ELECTROSTATICS */
679             felec            = qq30*(rinv30*rinvsq30-krf2);
680
681             fscal            = felec;
682
683             /* Calculate temporary vectorial force */
684             tx               = fscal*dx30;
685             ty               = fscal*dy30;
686             tz               = fscal*dz30;
687
688             /* Update vectorial force */
689             fix3            += tx;
690             fiy3            += ty;
691             fiz3            += tz;
692             f[j_coord_offset+DIM*0+XX] -= tx;
693             f[j_coord_offset+DIM*0+YY] -= ty;
694             f[j_coord_offset+DIM*0+ZZ] -= tz;
695
696             }
697
698             /* Inner loop uses 108 flops */
699         }
700         /* End of innermost loop */
701
702         tx = ty = tz = 0;
703         f[i_coord_offset+DIM*0+XX] += fix0;
704         f[i_coord_offset+DIM*0+YY] += fiy0;
705         f[i_coord_offset+DIM*0+ZZ] += fiz0;
706         tx                         += fix0;
707         ty                         += fiy0;
708         tz                         += fiz0;
709         f[i_coord_offset+DIM*1+XX] += fix1;
710         f[i_coord_offset+DIM*1+YY] += fiy1;
711         f[i_coord_offset+DIM*1+ZZ] += fiz1;
712         tx                         += fix1;
713         ty                         += fiy1;
714         tz                         += fiz1;
715         f[i_coord_offset+DIM*2+XX] += fix2;
716         f[i_coord_offset+DIM*2+YY] += fiy2;
717         f[i_coord_offset+DIM*2+ZZ] += fiz2;
718         tx                         += fix2;
719         ty                         += fiy2;
720         tz                         += fiz2;
721         f[i_coord_offset+DIM*3+XX] += fix3;
722         f[i_coord_offset+DIM*3+YY] += fiy3;
723         f[i_coord_offset+DIM*3+ZZ] += fiz3;
724         tx                         += fix3;
725         ty                         += fiy3;
726         tz                         += fiz3;
727         fshift[i_shift_offset+XX]  += tx;
728         fshift[i_shift_offset+YY]  += ty;
729         fshift[i_shift_offset+ZZ]  += tz;
730
731         /* Increment number of inner iterations */
732         inneriter                  += j_index_end - j_index_start;
733
734         /* Outer loop uses 39 flops */
735     }
736
737     /* Increment number of outer iterations */
738     outeriter        += nri;
739
740     /* Update outer/inner flops */
741
742     inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4_F,outeriter*39 + inneriter*108);
743 }