Remove all unnecessary HAVE_CONFIG_H
[alexxy/gromacs.git] / src / gromacs / gmxlib / nonbonded / nb_kernel_c / nb_kernel_ElecRFCut_VdwLJSw_GeomW3W3_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 "types/simple.h"
44 #include "gromacs/math/vec.h"
45 #include "nrnb.h"
46
47 /*
48  * Gromacs nonbonded kernel:   nb_kernel_ElecRFCut_VdwLJSw_GeomW3W3_VF_c
49  * Electrostatics interaction: ReactionField
50  * VdW interaction:            LennardJones
51  * Geometry:                   Water3-Water3
52  * Calculate force/pot:        PotentialAndForce
53  */
54 void
55 nb_kernel_ElecRFCut_VdwLJSw_GeomW3W3_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              vdwjidx0;
77     real             jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
78     int              vdwjidx1;
79     real             jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
80     int              vdwjidx2;
81     real             jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
82     real             dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00,cexp1_00,cexp2_00;
83     real             dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01,cexp1_01,cexp2_01;
84     real             dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02,cexp1_02,cexp2_02;
85     real             dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10,cexp1_10,cexp2_10;
86     real             dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11,cexp1_11,cexp2_11;
87     real             dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12,cexp1_12,cexp2_12;
88     real             dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20,cexp1_20,cexp2_20;
89     real             dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21,cexp1_21,cexp2_21;
90     real             dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22,cexp1_22,cexp2_22;
91     real             velec,felec,velecsum,facel,crf,krf,krf2;
92     real             *charge;
93     int              nvdwtype;
94     real             rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,br,vvdwexp,sh_vdw_invrcut6;
95     int              *vdwtype;
96     real             *vdwparam;
97     real             rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
98
99     x                = xx[0];
100     f                = ff[0];
101
102     nri              = nlist->nri;
103     iinr             = nlist->iinr;
104     jindex           = nlist->jindex;
105     jjnr             = nlist->jjnr;
106     shiftidx         = nlist->shift;
107     gid              = nlist->gid;
108     shiftvec         = fr->shift_vec[0];
109     fshift           = fr->fshift[0];
110     facel            = fr->epsfac;
111     charge           = mdatoms->chargeA;
112     krf              = fr->ic->k_rf;
113     krf2             = krf*2.0;
114     crf              = fr->ic->c_rf;
115     nvdwtype         = fr->ntype;
116     vdwparam         = fr->nbfp;
117     vdwtype          = mdatoms->typeA;
118
119     /* Setup water-specific parameters */
120     inr              = nlist->iinr[0];
121     iq0              = facel*charge[inr+0];
122     iq1              = facel*charge[inr+1];
123     iq2              = facel*charge[inr+2];
124     vdwioffset0      = 2*nvdwtype*vdwtype[inr+0];
125
126     jq0              = charge[inr+0];
127     jq1              = charge[inr+1];
128     jq2              = charge[inr+2];
129     vdwjidx0         = 2*vdwtype[inr+0];
130     qq00             = iq0*jq0;
131     c6_00            = vdwparam[vdwioffset0+vdwjidx0];
132     c12_00           = vdwparam[vdwioffset0+vdwjidx0+1];
133     qq01             = iq0*jq1;
134     qq02             = iq0*jq2;
135     qq10             = iq1*jq0;
136     qq11             = iq1*jq1;
137     qq12             = iq1*jq2;
138     qq20             = iq2*jq0;
139     qq21             = iq2*jq1;
140     qq22             = iq2*jq2;
141
142     /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
143     rcutoff          = fr->rcoulomb;
144     rcutoff2         = rcutoff*rcutoff;
145
146     rswitch          = fr->rvdw_switch;
147     /* Setup switch parameters */
148     d                = rcutoff-rswitch;
149     swV3             = -10.0/(d*d*d);
150     swV4             =  15.0/(d*d*d*d);
151     swV5             =  -6.0/(d*d*d*d*d);
152     swF2             = -30.0/(d*d*d);
153     swF3             =  60.0/(d*d*d*d);
154     swF4             = -30.0/(d*d*d*d*d);
155
156     outeriter        = 0;
157     inneriter        = 0;
158
159     /* Start outer loop over neighborlists */
160     for(iidx=0; iidx<nri; iidx++)
161     {
162         /* Load shift vector for this list */
163         i_shift_offset   = DIM*shiftidx[iidx];
164         shX              = shiftvec[i_shift_offset+XX];
165         shY              = shiftvec[i_shift_offset+YY];
166         shZ              = shiftvec[i_shift_offset+ZZ];
167
168         /* Load limits for loop over neighbors */
169         j_index_start    = jindex[iidx];
170         j_index_end      = jindex[iidx+1];
171
172         /* Get outer coordinate index */
173         inr              = iinr[iidx];
174         i_coord_offset   = DIM*inr;
175
176         /* Load i particle coords and add shift vector */
177         ix0              = shX + x[i_coord_offset+DIM*0+XX];
178         iy0              = shY + x[i_coord_offset+DIM*0+YY];
179         iz0              = shZ + x[i_coord_offset+DIM*0+ZZ];
180         ix1              = shX + x[i_coord_offset+DIM*1+XX];
181         iy1              = shY + x[i_coord_offset+DIM*1+YY];
182         iz1              = shZ + x[i_coord_offset+DIM*1+ZZ];
183         ix2              = shX + x[i_coord_offset+DIM*2+XX];
184         iy2              = shY + x[i_coord_offset+DIM*2+YY];
185         iz2              = shZ + x[i_coord_offset+DIM*2+ZZ];
186
187         fix0             = 0.0;
188         fiy0             = 0.0;
189         fiz0             = 0.0;
190         fix1             = 0.0;
191         fiy1             = 0.0;
192         fiz1             = 0.0;
193         fix2             = 0.0;
194         fiy2             = 0.0;
195         fiz2             = 0.0;
196
197         /* Reset potential sums */
198         velecsum         = 0.0;
199         vvdwsum          = 0.0;
200
201         /* Start inner kernel loop */
202         for(jidx=j_index_start; jidx<j_index_end; jidx++)
203         {
204             /* Get j neighbor index, and coordinate index */
205             jnr              = jjnr[jidx];
206             j_coord_offset   = DIM*jnr;
207
208             /* load j atom coordinates */
209             jx0              = x[j_coord_offset+DIM*0+XX];
210             jy0              = x[j_coord_offset+DIM*0+YY];
211             jz0              = x[j_coord_offset+DIM*0+ZZ];
212             jx1              = x[j_coord_offset+DIM*1+XX];
213             jy1              = x[j_coord_offset+DIM*1+YY];
214             jz1              = x[j_coord_offset+DIM*1+ZZ];
215             jx2              = x[j_coord_offset+DIM*2+XX];
216             jy2              = x[j_coord_offset+DIM*2+YY];
217             jz2              = x[j_coord_offset+DIM*2+ZZ];
218
219             /* Calculate displacement vector */
220             dx00             = ix0 - jx0;
221             dy00             = iy0 - jy0;
222             dz00             = iz0 - jz0;
223             dx01             = ix0 - jx1;
224             dy01             = iy0 - jy1;
225             dz01             = iz0 - jz1;
226             dx02             = ix0 - jx2;
227             dy02             = iy0 - jy2;
228             dz02             = iz0 - jz2;
229             dx10             = ix1 - jx0;
230             dy10             = iy1 - jy0;
231             dz10             = iz1 - jz0;
232             dx11             = ix1 - jx1;
233             dy11             = iy1 - jy1;
234             dz11             = iz1 - jz1;
235             dx12             = ix1 - jx2;
236             dy12             = iy1 - jy2;
237             dz12             = iz1 - jz2;
238             dx20             = ix2 - jx0;
239             dy20             = iy2 - jy0;
240             dz20             = iz2 - jz0;
241             dx21             = ix2 - jx1;
242             dy21             = iy2 - jy1;
243             dz21             = iz2 - jz1;
244             dx22             = ix2 - jx2;
245             dy22             = iy2 - jy2;
246             dz22             = iz2 - jz2;
247
248             /* Calculate squared distance and things based on it */
249             rsq00            = dx00*dx00+dy00*dy00+dz00*dz00;
250             rsq01            = dx01*dx01+dy01*dy01+dz01*dz01;
251             rsq02            = dx02*dx02+dy02*dy02+dz02*dz02;
252             rsq10            = dx10*dx10+dy10*dy10+dz10*dz10;
253             rsq11            = dx11*dx11+dy11*dy11+dz11*dz11;
254             rsq12            = dx12*dx12+dy12*dy12+dz12*dz12;
255             rsq20            = dx20*dx20+dy20*dy20+dz20*dz20;
256             rsq21            = dx21*dx21+dy21*dy21+dz21*dz21;
257             rsq22            = dx22*dx22+dy22*dy22+dz22*dz22;
258
259             rinv00           = gmx_invsqrt(rsq00);
260             rinv01           = gmx_invsqrt(rsq01);
261             rinv02           = gmx_invsqrt(rsq02);
262             rinv10           = gmx_invsqrt(rsq10);
263             rinv11           = gmx_invsqrt(rsq11);
264             rinv12           = gmx_invsqrt(rsq12);
265             rinv20           = gmx_invsqrt(rsq20);
266             rinv21           = gmx_invsqrt(rsq21);
267             rinv22           = gmx_invsqrt(rsq22);
268
269             rinvsq00         = rinv00*rinv00;
270             rinvsq01         = rinv01*rinv01;
271             rinvsq02         = rinv02*rinv02;
272             rinvsq10         = rinv10*rinv10;
273             rinvsq11         = rinv11*rinv11;
274             rinvsq12         = rinv12*rinv12;
275             rinvsq20         = rinv20*rinv20;
276             rinvsq21         = rinv21*rinv21;
277             rinvsq22         = rinv22*rinv22;
278
279             /**************************
280              * CALCULATE INTERACTIONS *
281              **************************/
282
283             if (rsq00<rcutoff2)
284             {
285
286             r00              = rsq00*rinv00;
287
288             /* REACTION-FIELD ELECTROSTATICS */
289             velec            = qq00*(rinv00+krf*rsq00-crf);
290             felec            = qq00*(rinv00*rinvsq00-krf2);
291
292             /* LENNARD-JONES DISPERSION/REPULSION */
293
294             rinvsix          = rinvsq00*rinvsq00*rinvsq00;
295             vvdw6            = c6_00*rinvsix;
296             vvdw12           = c12_00*rinvsix*rinvsix;
297             vvdw             = vvdw12*(1.0/12.0) - vvdw6*(1.0/6.0);
298             fvdw             = (vvdw12-vvdw6)*rinvsq00;
299
300             d                = r00-rswitch;
301             d                = (d>0.0) ? d : 0.0;
302             d2               = d*d;
303             sw               = 1.0+d2*d*(swV3+d*(swV4+d*swV5));
304
305             dsw              = d2*(swF2+d*(swF3+d*swF4));
306
307             /* Evaluate switch function */
308             /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
309             fvdw             = fvdw*sw - rinv00*vvdw*dsw;
310             vvdw            *= sw;
311
312             /* Update potential sums from outer loop */
313             velecsum        += velec;
314             vvdwsum         += vvdw;
315
316             fscal            = felec+fvdw;
317
318             /* Calculate temporary vectorial force */
319             tx               = fscal*dx00;
320             ty               = fscal*dy00;
321             tz               = fscal*dz00;
322
323             /* Update vectorial force */
324             fix0            += tx;
325             fiy0            += ty;
326             fiz0            += tz;
327             f[j_coord_offset+DIM*0+XX] -= tx;
328             f[j_coord_offset+DIM*0+YY] -= ty;
329             f[j_coord_offset+DIM*0+ZZ] -= tz;
330
331             }
332
333             /**************************
334              * CALCULATE INTERACTIONS *
335              **************************/
336
337             if (rsq01<rcutoff2)
338             {
339
340             /* REACTION-FIELD ELECTROSTATICS */
341             velec            = qq01*(rinv01+krf*rsq01-crf);
342             felec            = qq01*(rinv01*rinvsq01-krf2);
343
344             /* Update potential sums from outer loop */
345             velecsum        += velec;
346
347             fscal            = felec;
348
349             /* Calculate temporary vectorial force */
350             tx               = fscal*dx01;
351             ty               = fscal*dy01;
352             tz               = fscal*dz01;
353
354             /* Update vectorial force */
355             fix0            += tx;
356             fiy0            += ty;
357             fiz0            += tz;
358             f[j_coord_offset+DIM*1+XX] -= tx;
359             f[j_coord_offset+DIM*1+YY] -= ty;
360             f[j_coord_offset+DIM*1+ZZ] -= tz;
361
362             }
363
364             /**************************
365              * CALCULATE INTERACTIONS *
366              **************************/
367
368             if (rsq02<rcutoff2)
369             {
370
371             /* REACTION-FIELD ELECTROSTATICS */
372             velec            = qq02*(rinv02+krf*rsq02-crf);
373             felec            = qq02*(rinv02*rinvsq02-krf2);
374
375             /* Update potential sums from outer loop */
376             velecsum        += velec;
377
378             fscal            = felec;
379
380             /* Calculate temporary vectorial force */
381             tx               = fscal*dx02;
382             ty               = fscal*dy02;
383             tz               = fscal*dz02;
384
385             /* Update vectorial force */
386             fix0            += tx;
387             fiy0            += ty;
388             fiz0            += tz;
389             f[j_coord_offset+DIM*2+XX] -= tx;
390             f[j_coord_offset+DIM*2+YY] -= ty;
391             f[j_coord_offset+DIM*2+ZZ] -= tz;
392
393             }
394
395             /**************************
396              * CALCULATE INTERACTIONS *
397              **************************/
398
399             if (rsq10<rcutoff2)
400             {
401
402             /* REACTION-FIELD ELECTROSTATICS */
403             velec            = qq10*(rinv10+krf*rsq10-crf);
404             felec            = qq10*(rinv10*rinvsq10-krf2);
405
406             /* Update potential sums from outer loop */
407             velecsum        += velec;
408
409             fscal            = felec;
410
411             /* Calculate temporary vectorial force */
412             tx               = fscal*dx10;
413             ty               = fscal*dy10;
414             tz               = fscal*dz10;
415
416             /* Update vectorial force */
417             fix1            += tx;
418             fiy1            += ty;
419             fiz1            += tz;
420             f[j_coord_offset+DIM*0+XX] -= tx;
421             f[j_coord_offset+DIM*0+YY] -= ty;
422             f[j_coord_offset+DIM*0+ZZ] -= tz;
423
424             }
425
426             /**************************
427              * CALCULATE INTERACTIONS *
428              **************************/
429
430             if (rsq11<rcutoff2)
431             {
432
433             /* REACTION-FIELD ELECTROSTATICS */
434             velec            = qq11*(rinv11+krf*rsq11-crf);
435             felec            = qq11*(rinv11*rinvsq11-krf2);
436
437             /* Update potential sums from outer loop */
438             velecsum        += velec;
439
440             fscal            = felec;
441
442             /* Calculate temporary vectorial force */
443             tx               = fscal*dx11;
444             ty               = fscal*dy11;
445             tz               = fscal*dz11;
446
447             /* Update vectorial force */
448             fix1            += tx;
449             fiy1            += ty;
450             fiz1            += tz;
451             f[j_coord_offset+DIM*1+XX] -= tx;
452             f[j_coord_offset+DIM*1+YY] -= ty;
453             f[j_coord_offset+DIM*1+ZZ] -= tz;
454
455             }
456
457             /**************************
458              * CALCULATE INTERACTIONS *
459              **************************/
460
461             if (rsq12<rcutoff2)
462             {
463
464             /* REACTION-FIELD ELECTROSTATICS */
465             velec            = qq12*(rinv12+krf*rsq12-crf);
466             felec            = qq12*(rinv12*rinvsq12-krf2);
467
468             /* Update potential sums from outer loop */
469             velecsum        += velec;
470
471             fscal            = felec;
472
473             /* Calculate temporary vectorial force */
474             tx               = fscal*dx12;
475             ty               = fscal*dy12;
476             tz               = fscal*dz12;
477
478             /* Update vectorial force */
479             fix1            += tx;
480             fiy1            += ty;
481             fiz1            += tz;
482             f[j_coord_offset+DIM*2+XX] -= tx;
483             f[j_coord_offset+DIM*2+YY] -= ty;
484             f[j_coord_offset+DIM*2+ZZ] -= tz;
485
486             }
487
488             /**************************
489              * CALCULATE INTERACTIONS *
490              **************************/
491
492             if (rsq20<rcutoff2)
493             {
494
495             /* REACTION-FIELD ELECTROSTATICS */
496             velec            = qq20*(rinv20+krf*rsq20-crf);
497             felec            = qq20*(rinv20*rinvsq20-krf2);
498
499             /* Update potential sums from outer loop */
500             velecsum        += velec;
501
502             fscal            = felec;
503
504             /* Calculate temporary vectorial force */
505             tx               = fscal*dx20;
506             ty               = fscal*dy20;
507             tz               = fscal*dz20;
508
509             /* Update vectorial force */
510             fix2            += tx;
511             fiy2            += ty;
512             fiz2            += tz;
513             f[j_coord_offset+DIM*0+XX] -= tx;
514             f[j_coord_offset+DIM*0+YY] -= ty;
515             f[j_coord_offset+DIM*0+ZZ] -= tz;
516
517             }
518
519             /**************************
520              * CALCULATE INTERACTIONS *
521              **************************/
522
523             if (rsq21<rcutoff2)
524             {
525
526             /* REACTION-FIELD ELECTROSTATICS */
527             velec            = qq21*(rinv21+krf*rsq21-crf);
528             felec            = qq21*(rinv21*rinvsq21-krf2);
529
530             /* Update potential sums from outer loop */
531             velecsum        += velec;
532
533             fscal            = felec;
534
535             /* Calculate temporary vectorial force */
536             tx               = fscal*dx21;
537             ty               = fscal*dy21;
538             tz               = fscal*dz21;
539
540             /* Update vectorial force */
541             fix2            += tx;
542             fiy2            += ty;
543             fiz2            += tz;
544             f[j_coord_offset+DIM*1+XX] -= tx;
545             f[j_coord_offset+DIM*1+YY] -= ty;
546             f[j_coord_offset+DIM*1+ZZ] -= tz;
547
548             }
549
550             /**************************
551              * CALCULATE INTERACTIONS *
552              **************************/
553
554             if (rsq22<rcutoff2)
555             {
556
557             /* REACTION-FIELD ELECTROSTATICS */
558             velec            = qq22*(rinv22+krf*rsq22-crf);
559             felec            = qq22*(rinv22*rinvsq22-krf2);
560
561             /* Update potential sums from outer loop */
562             velecsum        += velec;
563
564             fscal            = felec;
565
566             /* Calculate temporary vectorial force */
567             tx               = fscal*dx22;
568             ty               = fscal*dy22;
569             tz               = fscal*dz22;
570
571             /* Update vectorial force */
572             fix2            += tx;
573             fiy2            += ty;
574             fiz2            += tz;
575             f[j_coord_offset+DIM*2+XX] -= tx;
576             f[j_coord_offset+DIM*2+YY] -= ty;
577             f[j_coord_offset+DIM*2+ZZ] -= tz;
578
579             }
580
581             /* Inner loop uses 310 flops */
582         }
583         /* End of innermost loop */
584
585         tx = ty = tz = 0;
586         f[i_coord_offset+DIM*0+XX] += fix0;
587         f[i_coord_offset+DIM*0+YY] += fiy0;
588         f[i_coord_offset+DIM*0+ZZ] += fiz0;
589         tx                         += fix0;
590         ty                         += fiy0;
591         tz                         += fiz0;
592         f[i_coord_offset+DIM*1+XX] += fix1;
593         f[i_coord_offset+DIM*1+YY] += fiy1;
594         f[i_coord_offset+DIM*1+ZZ] += fiz1;
595         tx                         += fix1;
596         ty                         += fiy1;
597         tz                         += fiz1;
598         f[i_coord_offset+DIM*2+XX] += fix2;
599         f[i_coord_offset+DIM*2+YY] += fiy2;
600         f[i_coord_offset+DIM*2+ZZ] += fiz2;
601         tx                         += fix2;
602         ty                         += fiy2;
603         tz                         += fiz2;
604         fshift[i_shift_offset+XX]  += tx;
605         fshift[i_shift_offset+YY]  += ty;
606         fshift[i_shift_offset+ZZ]  += tz;
607
608         ggid                        = gid[iidx];
609         /* Update potential energies */
610         kernel_data->energygrp_elec[ggid] += velecsum;
611         kernel_data->energygrp_vdw[ggid] += vvdwsum;
612
613         /* Increment number of inner iterations */
614         inneriter                  += j_index_end - j_index_start;
615
616         /* Outer loop uses 32 flops */
617     }
618
619     /* Increment number of outer iterations */
620     outeriter        += nri;
621
622     /* Update outer/inner flops */
623
624     inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_VF,outeriter*32 + inneriter*310);
625 }
626 /*
627  * Gromacs nonbonded kernel:   nb_kernel_ElecRFCut_VdwLJSw_GeomW3W3_F_c
628  * Electrostatics interaction: ReactionField
629  * VdW interaction:            LennardJones
630  * Geometry:                   Water3-Water3
631  * Calculate force/pot:        Force
632  */
633 void
634 nb_kernel_ElecRFCut_VdwLJSw_GeomW3W3_F_c
635                     (t_nblist                    * gmx_restrict       nlist,
636                      rvec                        * gmx_restrict          xx,
637                      rvec                        * gmx_restrict          ff,
638                      t_forcerec                  * gmx_restrict          fr,
639                      t_mdatoms                   * gmx_restrict     mdatoms,
640                      nb_kernel_data_t gmx_unused * gmx_restrict kernel_data,
641                      t_nrnb                      * gmx_restrict        nrnb)
642 {
643     int              i_shift_offset,i_coord_offset,j_coord_offset;
644     int              j_index_start,j_index_end;
645     int              nri,inr,ggid,iidx,jidx,jnr,outeriter,inneriter;
646     real             shX,shY,shZ,tx,ty,tz,fscal,rcutoff,rcutoff2;
647     int              *iinr,*jindex,*jjnr,*shiftidx,*gid;
648     real             *shiftvec,*fshift,*x,*f;
649     int              vdwioffset0;
650     real             ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
651     int              vdwioffset1;
652     real             ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
653     int              vdwioffset2;
654     real             ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
655     int              vdwjidx0;
656     real             jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
657     int              vdwjidx1;
658     real             jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
659     int              vdwjidx2;
660     real             jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
661     real             dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00,cexp1_00,cexp2_00;
662     real             dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01,cexp1_01,cexp2_01;
663     real             dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02,cexp1_02,cexp2_02;
664     real             dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10,cexp1_10,cexp2_10;
665     real             dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11,cexp1_11,cexp2_11;
666     real             dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12,cexp1_12,cexp2_12;
667     real             dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20,cexp1_20,cexp2_20;
668     real             dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21,cexp1_21,cexp2_21;
669     real             dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22,cexp1_22,cexp2_22;
670     real             velec,felec,velecsum,facel,crf,krf,krf2;
671     real             *charge;
672     int              nvdwtype;
673     real             rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,br,vvdwexp,sh_vdw_invrcut6;
674     int              *vdwtype;
675     real             *vdwparam;
676     real             rswitch,swV3,swV4,swV5,swF2,swF3,swF4,d,d2,sw,dsw;
677
678     x                = xx[0];
679     f                = ff[0];
680
681     nri              = nlist->nri;
682     iinr             = nlist->iinr;
683     jindex           = nlist->jindex;
684     jjnr             = nlist->jjnr;
685     shiftidx         = nlist->shift;
686     gid              = nlist->gid;
687     shiftvec         = fr->shift_vec[0];
688     fshift           = fr->fshift[0];
689     facel            = fr->epsfac;
690     charge           = mdatoms->chargeA;
691     krf              = fr->ic->k_rf;
692     krf2             = krf*2.0;
693     crf              = fr->ic->c_rf;
694     nvdwtype         = fr->ntype;
695     vdwparam         = fr->nbfp;
696     vdwtype          = mdatoms->typeA;
697
698     /* Setup water-specific parameters */
699     inr              = nlist->iinr[0];
700     iq0              = facel*charge[inr+0];
701     iq1              = facel*charge[inr+1];
702     iq2              = facel*charge[inr+2];
703     vdwioffset0      = 2*nvdwtype*vdwtype[inr+0];
704
705     jq0              = charge[inr+0];
706     jq1              = charge[inr+1];
707     jq2              = charge[inr+2];
708     vdwjidx0         = 2*vdwtype[inr+0];
709     qq00             = iq0*jq0;
710     c6_00            = vdwparam[vdwioffset0+vdwjidx0];
711     c12_00           = vdwparam[vdwioffset0+vdwjidx0+1];
712     qq01             = iq0*jq1;
713     qq02             = iq0*jq2;
714     qq10             = iq1*jq0;
715     qq11             = iq1*jq1;
716     qq12             = iq1*jq2;
717     qq20             = iq2*jq0;
718     qq21             = iq2*jq1;
719     qq22             = iq2*jq2;
720
721     /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
722     rcutoff          = fr->rcoulomb;
723     rcutoff2         = rcutoff*rcutoff;
724
725     rswitch          = fr->rvdw_switch;
726     /* Setup switch parameters */
727     d                = rcutoff-rswitch;
728     swV3             = -10.0/(d*d*d);
729     swV4             =  15.0/(d*d*d*d);
730     swV5             =  -6.0/(d*d*d*d*d);
731     swF2             = -30.0/(d*d*d);
732     swF3             =  60.0/(d*d*d*d);
733     swF4             = -30.0/(d*d*d*d*d);
734
735     outeriter        = 0;
736     inneriter        = 0;
737
738     /* Start outer loop over neighborlists */
739     for(iidx=0; iidx<nri; iidx++)
740     {
741         /* Load shift vector for this list */
742         i_shift_offset   = DIM*shiftidx[iidx];
743         shX              = shiftvec[i_shift_offset+XX];
744         shY              = shiftvec[i_shift_offset+YY];
745         shZ              = shiftvec[i_shift_offset+ZZ];
746
747         /* Load limits for loop over neighbors */
748         j_index_start    = jindex[iidx];
749         j_index_end      = jindex[iidx+1];
750
751         /* Get outer coordinate index */
752         inr              = iinr[iidx];
753         i_coord_offset   = DIM*inr;
754
755         /* Load i particle coords and add shift vector */
756         ix0              = shX + x[i_coord_offset+DIM*0+XX];
757         iy0              = shY + x[i_coord_offset+DIM*0+YY];
758         iz0              = shZ + x[i_coord_offset+DIM*0+ZZ];
759         ix1              = shX + x[i_coord_offset+DIM*1+XX];
760         iy1              = shY + x[i_coord_offset+DIM*1+YY];
761         iz1              = shZ + x[i_coord_offset+DIM*1+ZZ];
762         ix2              = shX + x[i_coord_offset+DIM*2+XX];
763         iy2              = shY + x[i_coord_offset+DIM*2+YY];
764         iz2              = shZ + x[i_coord_offset+DIM*2+ZZ];
765
766         fix0             = 0.0;
767         fiy0             = 0.0;
768         fiz0             = 0.0;
769         fix1             = 0.0;
770         fiy1             = 0.0;
771         fiz1             = 0.0;
772         fix2             = 0.0;
773         fiy2             = 0.0;
774         fiz2             = 0.0;
775
776         /* Start inner kernel loop */
777         for(jidx=j_index_start; jidx<j_index_end; jidx++)
778         {
779             /* Get j neighbor index, and coordinate index */
780             jnr              = jjnr[jidx];
781             j_coord_offset   = DIM*jnr;
782
783             /* load j atom coordinates */
784             jx0              = x[j_coord_offset+DIM*0+XX];
785             jy0              = x[j_coord_offset+DIM*0+YY];
786             jz0              = x[j_coord_offset+DIM*0+ZZ];
787             jx1              = x[j_coord_offset+DIM*1+XX];
788             jy1              = x[j_coord_offset+DIM*1+YY];
789             jz1              = x[j_coord_offset+DIM*1+ZZ];
790             jx2              = x[j_coord_offset+DIM*2+XX];
791             jy2              = x[j_coord_offset+DIM*2+YY];
792             jz2              = x[j_coord_offset+DIM*2+ZZ];
793
794             /* Calculate displacement vector */
795             dx00             = ix0 - jx0;
796             dy00             = iy0 - jy0;
797             dz00             = iz0 - jz0;
798             dx01             = ix0 - jx1;
799             dy01             = iy0 - jy1;
800             dz01             = iz0 - jz1;
801             dx02             = ix0 - jx2;
802             dy02             = iy0 - jy2;
803             dz02             = iz0 - jz2;
804             dx10             = ix1 - jx0;
805             dy10             = iy1 - jy0;
806             dz10             = iz1 - jz0;
807             dx11             = ix1 - jx1;
808             dy11             = iy1 - jy1;
809             dz11             = iz1 - jz1;
810             dx12             = ix1 - jx2;
811             dy12             = iy1 - jy2;
812             dz12             = iz1 - jz2;
813             dx20             = ix2 - jx0;
814             dy20             = iy2 - jy0;
815             dz20             = iz2 - jz0;
816             dx21             = ix2 - jx1;
817             dy21             = iy2 - jy1;
818             dz21             = iz2 - jz1;
819             dx22             = ix2 - jx2;
820             dy22             = iy2 - jy2;
821             dz22             = iz2 - jz2;
822
823             /* Calculate squared distance and things based on it */
824             rsq00            = dx00*dx00+dy00*dy00+dz00*dz00;
825             rsq01            = dx01*dx01+dy01*dy01+dz01*dz01;
826             rsq02            = dx02*dx02+dy02*dy02+dz02*dz02;
827             rsq10            = dx10*dx10+dy10*dy10+dz10*dz10;
828             rsq11            = dx11*dx11+dy11*dy11+dz11*dz11;
829             rsq12            = dx12*dx12+dy12*dy12+dz12*dz12;
830             rsq20            = dx20*dx20+dy20*dy20+dz20*dz20;
831             rsq21            = dx21*dx21+dy21*dy21+dz21*dz21;
832             rsq22            = dx22*dx22+dy22*dy22+dz22*dz22;
833
834             rinv00           = gmx_invsqrt(rsq00);
835             rinv01           = gmx_invsqrt(rsq01);
836             rinv02           = gmx_invsqrt(rsq02);
837             rinv10           = gmx_invsqrt(rsq10);
838             rinv11           = gmx_invsqrt(rsq11);
839             rinv12           = gmx_invsqrt(rsq12);
840             rinv20           = gmx_invsqrt(rsq20);
841             rinv21           = gmx_invsqrt(rsq21);
842             rinv22           = gmx_invsqrt(rsq22);
843
844             rinvsq00         = rinv00*rinv00;
845             rinvsq01         = rinv01*rinv01;
846             rinvsq02         = rinv02*rinv02;
847             rinvsq10         = rinv10*rinv10;
848             rinvsq11         = rinv11*rinv11;
849             rinvsq12         = rinv12*rinv12;
850             rinvsq20         = rinv20*rinv20;
851             rinvsq21         = rinv21*rinv21;
852             rinvsq22         = rinv22*rinv22;
853
854             /**************************
855              * CALCULATE INTERACTIONS *
856              **************************/
857
858             if (rsq00<rcutoff2)
859             {
860
861             r00              = rsq00*rinv00;
862
863             /* REACTION-FIELD ELECTROSTATICS */
864             felec            = qq00*(rinv00*rinvsq00-krf2);
865
866             /* LENNARD-JONES DISPERSION/REPULSION */
867
868             rinvsix          = rinvsq00*rinvsq00*rinvsq00;
869             vvdw6            = c6_00*rinvsix;
870             vvdw12           = c12_00*rinvsix*rinvsix;
871             vvdw             = vvdw12*(1.0/12.0) - vvdw6*(1.0/6.0);
872             fvdw             = (vvdw12-vvdw6)*rinvsq00;
873
874             d                = r00-rswitch;
875             d                = (d>0.0) ? d : 0.0;
876             d2               = d*d;
877             sw               = 1.0+d2*d*(swV3+d*(swV4+d*swV5));
878
879             dsw              = d2*(swF2+d*(swF3+d*swF4));
880
881             /* Evaluate switch function */
882             /* fscal'=f'/r=-(v*sw)'/r=-(v'*sw+v*dsw)/r=-v'*sw/r-v*dsw/r=fscal*sw-v*dsw/r */
883             fvdw             = fvdw*sw - rinv00*vvdw*dsw;
884
885             fscal            = felec+fvdw;
886
887             /* Calculate temporary vectorial force */
888             tx               = fscal*dx00;
889             ty               = fscal*dy00;
890             tz               = fscal*dz00;
891
892             /* Update vectorial force */
893             fix0            += tx;
894             fiy0            += ty;
895             fiz0            += tz;
896             f[j_coord_offset+DIM*0+XX] -= tx;
897             f[j_coord_offset+DIM*0+YY] -= ty;
898             f[j_coord_offset+DIM*0+ZZ] -= tz;
899
900             }
901
902             /**************************
903              * CALCULATE INTERACTIONS *
904              **************************/
905
906             if (rsq01<rcutoff2)
907             {
908
909             /* REACTION-FIELD ELECTROSTATICS */
910             felec            = qq01*(rinv01*rinvsq01-krf2);
911
912             fscal            = felec;
913
914             /* Calculate temporary vectorial force */
915             tx               = fscal*dx01;
916             ty               = fscal*dy01;
917             tz               = fscal*dz01;
918
919             /* Update vectorial force */
920             fix0            += tx;
921             fiy0            += ty;
922             fiz0            += tz;
923             f[j_coord_offset+DIM*1+XX] -= tx;
924             f[j_coord_offset+DIM*1+YY] -= ty;
925             f[j_coord_offset+DIM*1+ZZ] -= tz;
926
927             }
928
929             /**************************
930              * CALCULATE INTERACTIONS *
931              **************************/
932
933             if (rsq02<rcutoff2)
934             {
935
936             /* REACTION-FIELD ELECTROSTATICS */
937             felec            = qq02*(rinv02*rinvsq02-krf2);
938
939             fscal            = felec;
940
941             /* Calculate temporary vectorial force */
942             tx               = fscal*dx02;
943             ty               = fscal*dy02;
944             tz               = fscal*dz02;
945
946             /* Update vectorial force */
947             fix0            += tx;
948             fiy0            += ty;
949             fiz0            += tz;
950             f[j_coord_offset+DIM*2+XX] -= tx;
951             f[j_coord_offset+DIM*2+YY] -= ty;
952             f[j_coord_offset+DIM*2+ZZ] -= tz;
953
954             }
955
956             /**************************
957              * CALCULATE INTERACTIONS *
958              **************************/
959
960             if (rsq10<rcutoff2)
961             {
962
963             /* REACTION-FIELD ELECTROSTATICS */
964             felec            = qq10*(rinv10*rinvsq10-krf2);
965
966             fscal            = felec;
967
968             /* Calculate temporary vectorial force */
969             tx               = fscal*dx10;
970             ty               = fscal*dy10;
971             tz               = fscal*dz10;
972
973             /* Update vectorial force */
974             fix1            += tx;
975             fiy1            += ty;
976             fiz1            += tz;
977             f[j_coord_offset+DIM*0+XX] -= tx;
978             f[j_coord_offset+DIM*0+YY] -= ty;
979             f[j_coord_offset+DIM*0+ZZ] -= tz;
980
981             }
982
983             /**************************
984              * CALCULATE INTERACTIONS *
985              **************************/
986
987             if (rsq11<rcutoff2)
988             {
989
990             /* REACTION-FIELD ELECTROSTATICS */
991             felec            = qq11*(rinv11*rinvsq11-krf2);
992
993             fscal            = felec;
994
995             /* Calculate temporary vectorial force */
996             tx               = fscal*dx11;
997             ty               = fscal*dy11;
998             tz               = fscal*dz11;
999
1000             /* Update vectorial force */
1001             fix1            += tx;
1002             fiy1            += ty;
1003             fiz1            += tz;
1004             f[j_coord_offset+DIM*1+XX] -= tx;
1005             f[j_coord_offset+DIM*1+YY] -= ty;
1006             f[j_coord_offset+DIM*1+ZZ] -= tz;
1007
1008             }
1009
1010             /**************************
1011              * CALCULATE INTERACTIONS *
1012              **************************/
1013
1014             if (rsq12<rcutoff2)
1015             {
1016
1017             /* REACTION-FIELD ELECTROSTATICS */
1018             felec            = qq12*(rinv12*rinvsq12-krf2);
1019
1020             fscal            = felec;
1021
1022             /* Calculate temporary vectorial force */
1023             tx               = fscal*dx12;
1024             ty               = fscal*dy12;
1025             tz               = fscal*dz12;
1026
1027             /* Update vectorial force */
1028             fix1            += tx;
1029             fiy1            += ty;
1030             fiz1            += tz;
1031             f[j_coord_offset+DIM*2+XX] -= tx;
1032             f[j_coord_offset+DIM*2+YY] -= ty;
1033             f[j_coord_offset+DIM*2+ZZ] -= tz;
1034
1035             }
1036
1037             /**************************
1038              * CALCULATE INTERACTIONS *
1039              **************************/
1040
1041             if (rsq20<rcutoff2)
1042             {
1043
1044             /* REACTION-FIELD ELECTROSTATICS */
1045             felec            = qq20*(rinv20*rinvsq20-krf2);
1046
1047             fscal            = felec;
1048
1049             /* Calculate temporary vectorial force */
1050             tx               = fscal*dx20;
1051             ty               = fscal*dy20;
1052             tz               = fscal*dz20;
1053
1054             /* Update vectorial force */
1055             fix2            += tx;
1056             fiy2            += ty;
1057             fiz2            += tz;
1058             f[j_coord_offset+DIM*0+XX] -= tx;
1059             f[j_coord_offset+DIM*0+YY] -= ty;
1060             f[j_coord_offset+DIM*0+ZZ] -= tz;
1061
1062             }
1063
1064             /**************************
1065              * CALCULATE INTERACTIONS *
1066              **************************/
1067
1068             if (rsq21<rcutoff2)
1069             {
1070
1071             /* REACTION-FIELD ELECTROSTATICS */
1072             felec            = qq21*(rinv21*rinvsq21-krf2);
1073
1074             fscal            = felec;
1075
1076             /* Calculate temporary vectorial force */
1077             tx               = fscal*dx21;
1078             ty               = fscal*dy21;
1079             tz               = fscal*dz21;
1080
1081             /* Update vectorial force */
1082             fix2            += tx;
1083             fiy2            += ty;
1084             fiz2            += tz;
1085             f[j_coord_offset+DIM*1+XX] -= tx;
1086             f[j_coord_offset+DIM*1+YY] -= ty;
1087             f[j_coord_offset+DIM*1+ZZ] -= tz;
1088
1089             }
1090
1091             /**************************
1092              * CALCULATE INTERACTIONS *
1093              **************************/
1094
1095             if (rsq22<rcutoff2)
1096             {
1097
1098             /* REACTION-FIELD ELECTROSTATICS */
1099             felec            = qq22*(rinv22*rinvsq22-krf2);
1100
1101             fscal            = felec;
1102
1103             /* Calculate temporary vectorial force */
1104             tx               = fscal*dx22;
1105             ty               = fscal*dy22;
1106             tz               = fscal*dz22;
1107
1108             /* Update vectorial force */
1109             fix2            += tx;
1110             fiy2            += ty;
1111             fiz2            += tz;
1112             f[j_coord_offset+DIM*2+XX] -= tx;
1113             f[j_coord_offset+DIM*2+YY] -= ty;
1114             f[j_coord_offset+DIM*2+ZZ] -= tz;
1115
1116             }
1117
1118             /* Inner loop uses 263 flops */
1119         }
1120         /* End of innermost loop */
1121
1122         tx = ty = tz = 0;
1123         f[i_coord_offset+DIM*0+XX] += fix0;
1124         f[i_coord_offset+DIM*0+YY] += fiy0;
1125         f[i_coord_offset+DIM*0+ZZ] += fiz0;
1126         tx                         += fix0;
1127         ty                         += fiy0;
1128         tz                         += fiz0;
1129         f[i_coord_offset+DIM*1+XX] += fix1;
1130         f[i_coord_offset+DIM*1+YY] += fiy1;
1131         f[i_coord_offset+DIM*1+ZZ] += fiz1;
1132         tx                         += fix1;
1133         ty                         += fiy1;
1134         tz                         += fiz1;
1135         f[i_coord_offset+DIM*2+XX] += fix2;
1136         f[i_coord_offset+DIM*2+YY] += fiy2;
1137         f[i_coord_offset+DIM*2+ZZ] += fiz2;
1138         tx                         += fix2;
1139         ty                         += fiy2;
1140         tz                         += fiz2;
1141         fshift[i_shift_offset+XX]  += tx;
1142         fshift[i_shift_offset+YY]  += ty;
1143         fshift[i_shift_offset+ZZ]  += tz;
1144
1145         /* Increment number of inner iterations */
1146         inneriter                  += j_index_end - j_index_start;
1147
1148         /* Outer loop uses 30 flops */
1149     }
1150
1151     /* Increment number of outer iterations */
1152     outeriter        += nri;
1153
1154     /* Update outer/inner flops */
1155
1156     inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_F,outeriter*30 + inneriter*263);
1157 }