c3ed21c6438713340bb8ca135ffd6767ba773a37
[alexxy/gromacs.git] / src / gromacs / gmxlib / nonbonded / nb_kernel_sse2_double / nb_kernel_ElecRF_VdwCSTab_GeomW3W3_sse2_double.c
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2012,2013, by the GROMACS development team, led by
5  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6  * and including many others, as listed in the AUTHORS file in the
7  * top-level source directory and at http://www.gromacs.org.
8  *
9  * GROMACS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1
12  * of the License, or (at your option) any later version.
13  *
14  * GROMACS is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with GROMACS; if not, see
21  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
23  *
24  * If you want to redistribute modifications to GROMACS, please
25  * consider that scientific software is very special. Version
26  * control is crucial - bugs must be traceable. We will be happy to
27  * consider code for inclusion in the official distribution, but
28  * derived work must not be called official GROMACS. Details are found
29  * in the README & COPYING files - if they are missing, get the
30  * official version at http://www.gromacs.org.
31  *
32  * To help us fund GROMACS development, we humbly ask that you cite
33  * the research papers on the package. Check out http://www.gromacs.org.
34  */
35 /*
36  * Note: this file was generated by the GROMACS sse2_double kernel generator.
37  */
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif
41
42 #include <math.h>
43
44 #include "../nb_kernel.h"
45 #include "types/simple.h"
46 #include "vec.h"
47 #include "nrnb.h"
48
49 #include "gmx_math_x86_sse2_double.h"
50 #include "kernelutil_x86_sse2_double.h"
51
52 /*
53  * Gromacs nonbonded kernel:   nb_kernel_ElecRF_VdwCSTab_GeomW3W3_VF_sse2_double
54  * Electrostatics interaction: ReactionField
55  * VdW interaction:            CubicSplineTable
56  * Geometry:                   Water3-Water3
57  * Calculate force/pot:        PotentialAndForce
58  */
59 void
60 nb_kernel_ElecRF_VdwCSTab_GeomW3W3_VF_sse2_double
61                     (t_nblist                    * gmx_restrict       nlist,
62                      rvec                        * gmx_restrict          xx,
63                      rvec                        * gmx_restrict          ff,
64                      t_forcerec                  * gmx_restrict          fr,
65                      t_mdatoms                   * gmx_restrict     mdatoms,
66                      nb_kernel_data_t gmx_unused * gmx_restrict kernel_data,
67                      t_nrnb                      * gmx_restrict        nrnb)
68 {
69     /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
70      * just 0 for non-waters.
71      * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
72      * jnr indices corresponding to data put in the four positions in the SIMD register.
73      */
74     int              i_shift_offset,i_coord_offset,outeriter,inneriter;
75     int              j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
76     int              jnrA,jnrB;
77     int              j_coord_offsetA,j_coord_offsetB;
78     int              *iinr,*jindex,*jjnr,*shiftidx,*gid;
79     real             rcutoff_scalar;
80     real             *shiftvec,*fshift,*x,*f;
81     __m128d          tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
82     int              vdwioffset0;
83     __m128d          ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
84     int              vdwioffset1;
85     __m128d          ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
86     int              vdwioffset2;
87     __m128d          ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
88     int              vdwjidx0A,vdwjidx0B;
89     __m128d          jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
90     int              vdwjidx1A,vdwjidx1B;
91     __m128d          jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
92     int              vdwjidx2A,vdwjidx2B;
93     __m128d          jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
94     __m128d          dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
95     __m128d          dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
96     __m128d          dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
97     __m128d          dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
98     __m128d          dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
99     __m128d          dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
100     __m128d          dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
101     __m128d          dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
102     __m128d          dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
103     __m128d          velec,felec,velecsum,facel,crf,krf,krf2;
104     real             *charge;
105     int              nvdwtype;
106     __m128d          rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
107     int              *vdwtype;
108     real             *vdwparam;
109     __m128d          one_sixth   = _mm_set1_pd(1.0/6.0);
110     __m128d          one_twelfth = _mm_set1_pd(1.0/12.0);
111     __m128i          vfitab;
112     __m128i          ifour       = _mm_set1_epi32(4);
113     __m128d          rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
114     real             *vftab;
115     __m128d          dummy_mask,cutoff_mask;
116     __m128d          signbit   = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
117     __m128d          one     = _mm_set1_pd(1.0);
118     __m128d          two     = _mm_set1_pd(2.0);
119     x                = xx[0];
120     f                = ff[0];
121
122     nri              = nlist->nri;
123     iinr             = nlist->iinr;
124     jindex           = nlist->jindex;
125     jjnr             = nlist->jjnr;
126     shiftidx         = nlist->shift;
127     gid              = nlist->gid;
128     shiftvec         = fr->shift_vec[0];
129     fshift           = fr->fshift[0];
130     facel            = _mm_set1_pd(fr->epsfac);
131     charge           = mdatoms->chargeA;
132     krf              = _mm_set1_pd(fr->ic->k_rf);
133     krf2             = _mm_set1_pd(fr->ic->k_rf*2.0);
134     crf              = _mm_set1_pd(fr->ic->c_rf);
135     nvdwtype         = fr->ntype;
136     vdwparam         = fr->nbfp;
137     vdwtype          = mdatoms->typeA;
138
139     vftab            = kernel_data->table_vdw->data;
140     vftabscale       = _mm_set1_pd(kernel_data->table_vdw->scale);
141
142     /* Setup water-specific parameters */
143     inr              = nlist->iinr[0];
144     iq0              = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
145     iq1              = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
146     iq2              = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
147     vdwioffset0      = 2*nvdwtype*vdwtype[inr+0];
148
149     jq0              = _mm_set1_pd(charge[inr+0]);
150     jq1              = _mm_set1_pd(charge[inr+1]);
151     jq2              = _mm_set1_pd(charge[inr+2]);
152     vdwjidx0A        = 2*vdwtype[inr+0];
153     qq00             = _mm_mul_pd(iq0,jq0);
154     c6_00            = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
155     c12_00           = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
156     qq01             = _mm_mul_pd(iq0,jq1);
157     qq02             = _mm_mul_pd(iq0,jq2);
158     qq10             = _mm_mul_pd(iq1,jq0);
159     qq11             = _mm_mul_pd(iq1,jq1);
160     qq12             = _mm_mul_pd(iq1,jq2);
161     qq20             = _mm_mul_pd(iq2,jq0);
162     qq21             = _mm_mul_pd(iq2,jq1);
163     qq22             = _mm_mul_pd(iq2,jq2);
164
165     /* Avoid stupid compiler warnings */
166     jnrA = jnrB = 0;
167     j_coord_offsetA = 0;
168     j_coord_offsetB = 0;
169
170     outeriter        = 0;
171     inneriter        = 0;
172
173     /* Start outer loop over neighborlists */
174     for(iidx=0; iidx<nri; iidx++)
175     {
176         /* Load shift vector for this list */
177         i_shift_offset   = DIM*shiftidx[iidx];
178
179         /* Load limits for loop over neighbors */
180         j_index_start    = jindex[iidx];
181         j_index_end      = jindex[iidx+1];
182
183         /* Get outer coordinate index */
184         inr              = iinr[iidx];
185         i_coord_offset   = DIM*inr;
186
187         /* Load i particle coords and add shift vector */
188         gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
189                                                  &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
190
191         fix0             = _mm_setzero_pd();
192         fiy0             = _mm_setzero_pd();
193         fiz0             = _mm_setzero_pd();
194         fix1             = _mm_setzero_pd();
195         fiy1             = _mm_setzero_pd();
196         fiz1             = _mm_setzero_pd();
197         fix2             = _mm_setzero_pd();
198         fiy2             = _mm_setzero_pd();
199         fiz2             = _mm_setzero_pd();
200
201         /* Reset potential sums */
202         velecsum         = _mm_setzero_pd();
203         vvdwsum          = _mm_setzero_pd();
204
205         /* Start inner kernel loop */
206         for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
207         {
208
209             /* Get j neighbor index, and coordinate index */
210             jnrA             = jjnr[jidx];
211             jnrB             = jjnr[jidx+1];
212             j_coord_offsetA  = DIM*jnrA;
213             j_coord_offsetB  = DIM*jnrB;
214
215             /* load j atom coordinates */
216             gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
217                                               &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
218
219             /* Calculate displacement vector */
220             dx00             = _mm_sub_pd(ix0,jx0);
221             dy00             = _mm_sub_pd(iy0,jy0);
222             dz00             = _mm_sub_pd(iz0,jz0);
223             dx01             = _mm_sub_pd(ix0,jx1);
224             dy01             = _mm_sub_pd(iy0,jy1);
225             dz01             = _mm_sub_pd(iz0,jz1);
226             dx02             = _mm_sub_pd(ix0,jx2);
227             dy02             = _mm_sub_pd(iy0,jy2);
228             dz02             = _mm_sub_pd(iz0,jz2);
229             dx10             = _mm_sub_pd(ix1,jx0);
230             dy10             = _mm_sub_pd(iy1,jy0);
231             dz10             = _mm_sub_pd(iz1,jz0);
232             dx11             = _mm_sub_pd(ix1,jx1);
233             dy11             = _mm_sub_pd(iy1,jy1);
234             dz11             = _mm_sub_pd(iz1,jz1);
235             dx12             = _mm_sub_pd(ix1,jx2);
236             dy12             = _mm_sub_pd(iy1,jy2);
237             dz12             = _mm_sub_pd(iz1,jz2);
238             dx20             = _mm_sub_pd(ix2,jx0);
239             dy20             = _mm_sub_pd(iy2,jy0);
240             dz20             = _mm_sub_pd(iz2,jz0);
241             dx21             = _mm_sub_pd(ix2,jx1);
242             dy21             = _mm_sub_pd(iy2,jy1);
243             dz21             = _mm_sub_pd(iz2,jz1);
244             dx22             = _mm_sub_pd(ix2,jx2);
245             dy22             = _mm_sub_pd(iy2,jy2);
246             dz22             = _mm_sub_pd(iz2,jz2);
247
248             /* Calculate squared distance and things based on it */
249             rsq00            = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
250             rsq01            = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
251             rsq02            = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
252             rsq10            = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
253             rsq11            = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
254             rsq12            = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
255             rsq20            = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
256             rsq21            = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
257             rsq22            = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
258
259             rinv00           = gmx_mm_invsqrt_pd(rsq00);
260             rinv01           = gmx_mm_invsqrt_pd(rsq01);
261             rinv02           = gmx_mm_invsqrt_pd(rsq02);
262             rinv10           = gmx_mm_invsqrt_pd(rsq10);
263             rinv11           = gmx_mm_invsqrt_pd(rsq11);
264             rinv12           = gmx_mm_invsqrt_pd(rsq12);
265             rinv20           = gmx_mm_invsqrt_pd(rsq20);
266             rinv21           = gmx_mm_invsqrt_pd(rsq21);
267             rinv22           = gmx_mm_invsqrt_pd(rsq22);
268
269             rinvsq00         = _mm_mul_pd(rinv00,rinv00);
270             rinvsq01         = _mm_mul_pd(rinv01,rinv01);
271             rinvsq02         = _mm_mul_pd(rinv02,rinv02);
272             rinvsq10         = _mm_mul_pd(rinv10,rinv10);
273             rinvsq11         = _mm_mul_pd(rinv11,rinv11);
274             rinvsq12         = _mm_mul_pd(rinv12,rinv12);
275             rinvsq20         = _mm_mul_pd(rinv20,rinv20);
276             rinvsq21         = _mm_mul_pd(rinv21,rinv21);
277             rinvsq22         = _mm_mul_pd(rinv22,rinv22);
278
279             fjx0             = _mm_setzero_pd();
280             fjy0             = _mm_setzero_pd();
281             fjz0             = _mm_setzero_pd();
282             fjx1             = _mm_setzero_pd();
283             fjy1             = _mm_setzero_pd();
284             fjz1             = _mm_setzero_pd();
285             fjx2             = _mm_setzero_pd();
286             fjy2             = _mm_setzero_pd();
287             fjz2             = _mm_setzero_pd();
288
289             /**************************
290              * CALCULATE INTERACTIONS *
291              **************************/
292
293             r00              = _mm_mul_pd(rsq00,rinv00);
294
295             /* Calculate table index by multiplying r with table scale and truncate to integer */
296             rt               = _mm_mul_pd(r00,vftabscale);
297             vfitab           = _mm_cvttpd_epi32(rt);
298             vfeps            = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
299             vfitab           = _mm_slli_epi32(vfitab,3);
300
301             /* REACTION-FIELD ELECTROSTATICS */
302             velec            = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
303             felec            = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
304
305             /* CUBIC SPLINE TABLE DISPERSION */
306             Y                = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
307             F                = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
308             GMX_MM_TRANSPOSE2_PD(Y,F);
309             G                = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
310             H                = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
311             GMX_MM_TRANSPOSE2_PD(G,H);
312             Heps             = _mm_mul_pd(vfeps,H);
313             Fp               = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
314             VV               = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
315             vvdw6            = _mm_mul_pd(c6_00,VV);
316             FF               = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
317             fvdw6            = _mm_mul_pd(c6_00,FF);
318
319             /* CUBIC SPLINE TABLE REPULSION */
320             vfitab           = _mm_add_epi32(vfitab,ifour);
321             Y                = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
322             F                = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
323             GMX_MM_TRANSPOSE2_PD(Y,F);
324             G                = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
325             H                = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
326             GMX_MM_TRANSPOSE2_PD(G,H);
327             Heps             = _mm_mul_pd(vfeps,H);
328             Fp               = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
329             VV               = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
330             vvdw12           = _mm_mul_pd(c12_00,VV);
331             FF               = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
332             fvdw12           = _mm_mul_pd(c12_00,FF);
333             vvdw             = _mm_add_pd(vvdw12,vvdw6);
334             fvdw             = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
335
336             /* Update potential sum for this i atom from the interaction with this j atom. */
337             velecsum         = _mm_add_pd(velecsum,velec);
338             vvdwsum          = _mm_add_pd(vvdwsum,vvdw);
339
340             fscal            = _mm_add_pd(felec,fvdw);
341
342             /* Calculate temporary vectorial force */
343             tx               = _mm_mul_pd(fscal,dx00);
344             ty               = _mm_mul_pd(fscal,dy00);
345             tz               = _mm_mul_pd(fscal,dz00);
346
347             /* Update vectorial force */
348             fix0             = _mm_add_pd(fix0,tx);
349             fiy0             = _mm_add_pd(fiy0,ty);
350             fiz0             = _mm_add_pd(fiz0,tz);
351
352             fjx0             = _mm_add_pd(fjx0,tx);
353             fjy0             = _mm_add_pd(fjy0,ty);
354             fjz0             = _mm_add_pd(fjz0,tz);
355
356             /**************************
357              * CALCULATE INTERACTIONS *
358              **************************/
359
360             /* REACTION-FIELD ELECTROSTATICS */
361             velec            = _mm_mul_pd(qq01,_mm_sub_pd(_mm_add_pd(rinv01,_mm_mul_pd(krf,rsq01)),crf));
362             felec            = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
363
364             /* Update potential sum for this i atom from the interaction with this j atom. */
365             velecsum         = _mm_add_pd(velecsum,velec);
366
367             fscal            = felec;
368
369             /* Calculate temporary vectorial force */
370             tx               = _mm_mul_pd(fscal,dx01);
371             ty               = _mm_mul_pd(fscal,dy01);
372             tz               = _mm_mul_pd(fscal,dz01);
373
374             /* Update vectorial force */
375             fix0             = _mm_add_pd(fix0,tx);
376             fiy0             = _mm_add_pd(fiy0,ty);
377             fiz0             = _mm_add_pd(fiz0,tz);
378
379             fjx1             = _mm_add_pd(fjx1,tx);
380             fjy1             = _mm_add_pd(fjy1,ty);
381             fjz1             = _mm_add_pd(fjz1,tz);
382
383             /**************************
384              * CALCULATE INTERACTIONS *
385              **************************/
386
387             /* REACTION-FIELD ELECTROSTATICS */
388             velec            = _mm_mul_pd(qq02,_mm_sub_pd(_mm_add_pd(rinv02,_mm_mul_pd(krf,rsq02)),crf));
389             felec            = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
390
391             /* Update potential sum for this i atom from the interaction with this j atom. */
392             velecsum         = _mm_add_pd(velecsum,velec);
393
394             fscal            = felec;
395
396             /* Calculate temporary vectorial force */
397             tx               = _mm_mul_pd(fscal,dx02);
398             ty               = _mm_mul_pd(fscal,dy02);
399             tz               = _mm_mul_pd(fscal,dz02);
400
401             /* Update vectorial force */
402             fix0             = _mm_add_pd(fix0,tx);
403             fiy0             = _mm_add_pd(fiy0,ty);
404             fiz0             = _mm_add_pd(fiz0,tz);
405
406             fjx2             = _mm_add_pd(fjx2,tx);
407             fjy2             = _mm_add_pd(fjy2,ty);
408             fjz2             = _mm_add_pd(fjz2,tz);
409
410             /**************************
411              * CALCULATE INTERACTIONS *
412              **************************/
413
414             /* REACTION-FIELD ELECTROSTATICS */
415             velec            = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
416             felec            = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
417
418             /* Update potential sum for this i atom from the interaction with this j atom. */
419             velecsum         = _mm_add_pd(velecsum,velec);
420
421             fscal            = felec;
422
423             /* Calculate temporary vectorial force */
424             tx               = _mm_mul_pd(fscal,dx10);
425             ty               = _mm_mul_pd(fscal,dy10);
426             tz               = _mm_mul_pd(fscal,dz10);
427
428             /* Update vectorial force */
429             fix1             = _mm_add_pd(fix1,tx);
430             fiy1             = _mm_add_pd(fiy1,ty);
431             fiz1             = _mm_add_pd(fiz1,tz);
432
433             fjx0             = _mm_add_pd(fjx0,tx);
434             fjy0             = _mm_add_pd(fjy0,ty);
435             fjz0             = _mm_add_pd(fjz0,tz);
436
437             /**************************
438              * CALCULATE INTERACTIONS *
439              **************************/
440
441             /* REACTION-FIELD ELECTROSTATICS */
442             velec            = _mm_mul_pd(qq11,_mm_sub_pd(_mm_add_pd(rinv11,_mm_mul_pd(krf,rsq11)),crf));
443             felec            = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
444
445             /* Update potential sum for this i atom from the interaction with this j atom. */
446             velecsum         = _mm_add_pd(velecsum,velec);
447
448             fscal            = felec;
449
450             /* Calculate temporary vectorial force */
451             tx               = _mm_mul_pd(fscal,dx11);
452             ty               = _mm_mul_pd(fscal,dy11);
453             tz               = _mm_mul_pd(fscal,dz11);
454
455             /* Update vectorial force */
456             fix1             = _mm_add_pd(fix1,tx);
457             fiy1             = _mm_add_pd(fiy1,ty);
458             fiz1             = _mm_add_pd(fiz1,tz);
459
460             fjx1             = _mm_add_pd(fjx1,tx);
461             fjy1             = _mm_add_pd(fjy1,ty);
462             fjz1             = _mm_add_pd(fjz1,tz);
463
464             /**************************
465              * CALCULATE INTERACTIONS *
466              **************************/
467
468             /* REACTION-FIELD ELECTROSTATICS */
469             velec            = _mm_mul_pd(qq12,_mm_sub_pd(_mm_add_pd(rinv12,_mm_mul_pd(krf,rsq12)),crf));
470             felec            = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
471
472             /* Update potential sum for this i atom from the interaction with this j atom. */
473             velecsum         = _mm_add_pd(velecsum,velec);
474
475             fscal            = felec;
476
477             /* Calculate temporary vectorial force */
478             tx               = _mm_mul_pd(fscal,dx12);
479             ty               = _mm_mul_pd(fscal,dy12);
480             tz               = _mm_mul_pd(fscal,dz12);
481
482             /* Update vectorial force */
483             fix1             = _mm_add_pd(fix1,tx);
484             fiy1             = _mm_add_pd(fiy1,ty);
485             fiz1             = _mm_add_pd(fiz1,tz);
486
487             fjx2             = _mm_add_pd(fjx2,tx);
488             fjy2             = _mm_add_pd(fjy2,ty);
489             fjz2             = _mm_add_pd(fjz2,tz);
490
491             /**************************
492              * CALCULATE INTERACTIONS *
493              **************************/
494
495             /* REACTION-FIELD ELECTROSTATICS */
496             velec            = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
497             felec            = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
498
499             /* Update potential sum for this i atom from the interaction with this j atom. */
500             velecsum         = _mm_add_pd(velecsum,velec);
501
502             fscal            = felec;
503
504             /* Calculate temporary vectorial force */
505             tx               = _mm_mul_pd(fscal,dx20);
506             ty               = _mm_mul_pd(fscal,dy20);
507             tz               = _mm_mul_pd(fscal,dz20);
508
509             /* Update vectorial force */
510             fix2             = _mm_add_pd(fix2,tx);
511             fiy2             = _mm_add_pd(fiy2,ty);
512             fiz2             = _mm_add_pd(fiz2,tz);
513
514             fjx0             = _mm_add_pd(fjx0,tx);
515             fjy0             = _mm_add_pd(fjy0,ty);
516             fjz0             = _mm_add_pd(fjz0,tz);
517
518             /**************************
519              * CALCULATE INTERACTIONS *
520              **************************/
521
522             /* REACTION-FIELD ELECTROSTATICS */
523             velec            = _mm_mul_pd(qq21,_mm_sub_pd(_mm_add_pd(rinv21,_mm_mul_pd(krf,rsq21)),crf));
524             felec            = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
525
526             /* Update potential sum for this i atom from the interaction with this j atom. */
527             velecsum         = _mm_add_pd(velecsum,velec);
528
529             fscal            = felec;
530
531             /* Calculate temporary vectorial force */
532             tx               = _mm_mul_pd(fscal,dx21);
533             ty               = _mm_mul_pd(fscal,dy21);
534             tz               = _mm_mul_pd(fscal,dz21);
535
536             /* Update vectorial force */
537             fix2             = _mm_add_pd(fix2,tx);
538             fiy2             = _mm_add_pd(fiy2,ty);
539             fiz2             = _mm_add_pd(fiz2,tz);
540
541             fjx1             = _mm_add_pd(fjx1,tx);
542             fjy1             = _mm_add_pd(fjy1,ty);
543             fjz1             = _mm_add_pd(fjz1,tz);
544
545             /**************************
546              * CALCULATE INTERACTIONS *
547              **************************/
548
549             /* REACTION-FIELD ELECTROSTATICS */
550             velec            = _mm_mul_pd(qq22,_mm_sub_pd(_mm_add_pd(rinv22,_mm_mul_pd(krf,rsq22)),crf));
551             felec            = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
552
553             /* Update potential sum for this i atom from the interaction with this j atom. */
554             velecsum         = _mm_add_pd(velecsum,velec);
555
556             fscal            = felec;
557
558             /* Calculate temporary vectorial force */
559             tx               = _mm_mul_pd(fscal,dx22);
560             ty               = _mm_mul_pd(fscal,dy22);
561             tz               = _mm_mul_pd(fscal,dz22);
562
563             /* Update vectorial force */
564             fix2             = _mm_add_pd(fix2,tx);
565             fiy2             = _mm_add_pd(fiy2,ty);
566             fiz2             = _mm_add_pd(fiz2,tz);
567
568             fjx2             = _mm_add_pd(fjx2,tx);
569             fjy2             = _mm_add_pd(fjy2,ty);
570             fjz2             = _mm_add_pd(fjz2,tz);
571
572             gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
573
574             /* Inner loop uses 323 flops */
575         }
576
577         if(jidx<j_index_end)
578         {
579
580             jnrA             = jjnr[jidx];
581             j_coord_offsetA  = DIM*jnrA;
582
583             /* load j atom coordinates */
584             gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
585                                               &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
586
587             /* Calculate displacement vector */
588             dx00             = _mm_sub_pd(ix0,jx0);
589             dy00             = _mm_sub_pd(iy0,jy0);
590             dz00             = _mm_sub_pd(iz0,jz0);
591             dx01             = _mm_sub_pd(ix0,jx1);
592             dy01             = _mm_sub_pd(iy0,jy1);
593             dz01             = _mm_sub_pd(iz0,jz1);
594             dx02             = _mm_sub_pd(ix0,jx2);
595             dy02             = _mm_sub_pd(iy0,jy2);
596             dz02             = _mm_sub_pd(iz0,jz2);
597             dx10             = _mm_sub_pd(ix1,jx0);
598             dy10             = _mm_sub_pd(iy1,jy0);
599             dz10             = _mm_sub_pd(iz1,jz0);
600             dx11             = _mm_sub_pd(ix1,jx1);
601             dy11             = _mm_sub_pd(iy1,jy1);
602             dz11             = _mm_sub_pd(iz1,jz1);
603             dx12             = _mm_sub_pd(ix1,jx2);
604             dy12             = _mm_sub_pd(iy1,jy2);
605             dz12             = _mm_sub_pd(iz1,jz2);
606             dx20             = _mm_sub_pd(ix2,jx0);
607             dy20             = _mm_sub_pd(iy2,jy0);
608             dz20             = _mm_sub_pd(iz2,jz0);
609             dx21             = _mm_sub_pd(ix2,jx1);
610             dy21             = _mm_sub_pd(iy2,jy1);
611             dz21             = _mm_sub_pd(iz2,jz1);
612             dx22             = _mm_sub_pd(ix2,jx2);
613             dy22             = _mm_sub_pd(iy2,jy2);
614             dz22             = _mm_sub_pd(iz2,jz2);
615
616             /* Calculate squared distance and things based on it */
617             rsq00            = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
618             rsq01            = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
619             rsq02            = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
620             rsq10            = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
621             rsq11            = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
622             rsq12            = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
623             rsq20            = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
624             rsq21            = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
625             rsq22            = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
626
627             rinv00           = gmx_mm_invsqrt_pd(rsq00);
628             rinv01           = gmx_mm_invsqrt_pd(rsq01);
629             rinv02           = gmx_mm_invsqrt_pd(rsq02);
630             rinv10           = gmx_mm_invsqrt_pd(rsq10);
631             rinv11           = gmx_mm_invsqrt_pd(rsq11);
632             rinv12           = gmx_mm_invsqrt_pd(rsq12);
633             rinv20           = gmx_mm_invsqrt_pd(rsq20);
634             rinv21           = gmx_mm_invsqrt_pd(rsq21);
635             rinv22           = gmx_mm_invsqrt_pd(rsq22);
636
637             rinvsq00         = _mm_mul_pd(rinv00,rinv00);
638             rinvsq01         = _mm_mul_pd(rinv01,rinv01);
639             rinvsq02         = _mm_mul_pd(rinv02,rinv02);
640             rinvsq10         = _mm_mul_pd(rinv10,rinv10);
641             rinvsq11         = _mm_mul_pd(rinv11,rinv11);
642             rinvsq12         = _mm_mul_pd(rinv12,rinv12);
643             rinvsq20         = _mm_mul_pd(rinv20,rinv20);
644             rinvsq21         = _mm_mul_pd(rinv21,rinv21);
645             rinvsq22         = _mm_mul_pd(rinv22,rinv22);
646
647             fjx0             = _mm_setzero_pd();
648             fjy0             = _mm_setzero_pd();
649             fjz0             = _mm_setzero_pd();
650             fjx1             = _mm_setzero_pd();
651             fjy1             = _mm_setzero_pd();
652             fjz1             = _mm_setzero_pd();
653             fjx2             = _mm_setzero_pd();
654             fjy2             = _mm_setzero_pd();
655             fjz2             = _mm_setzero_pd();
656
657             /**************************
658              * CALCULATE INTERACTIONS *
659              **************************/
660
661             r00              = _mm_mul_pd(rsq00,rinv00);
662
663             /* Calculate table index by multiplying r with table scale and truncate to integer */
664             rt               = _mm_mul_pd(r00,vftabscale);
665             vfitab           = _mm_cvttpd_epi32(rt);
666             vfeps            = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
667             vfitab           = _mm_slli_epi32(vfitab,3);
668
669             /* REACTION-FIELD ELECTROSTATICS */
670             velec            = _mm_mul_pd(qq00,_mm_sub_pd(_mm_add_pd(rinv00,_mm_mul_pd(krf,rsq00)),crf));
671             felec            = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
672
673             /* CUBIC SPLINE TABLE DISPERSION */
674             Y                = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
675             F                = _mm_setzero_pd();
676             GMX_MM_TRANSPOSE2_PD(Y,F);
677             G                = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
678             H                = _mm_setzero_pd();
679             GMX_MM_TRANSPOSE2_PD(G,H);
680             Heps             = _mm_mul_pd(vfeps,H);
681             Fp               = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
682             VV               = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
683             vvdw6            = _mm_mul_pd(c6_00,VV);
684             FF               = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
685             fvdw6            = _mm_mul_pd(c6_00,FF);
686
687             /* CUBIC SPLINE TABLE REPULSION */
688             vfitab           = _mm_add_epi32(vfitab,ifour);
689             Y                = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
690             F                = _mm_setzero_pd();
691             GMX_MM_TRANSPOSE2_PD(Y,F);
692             G                = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
693             H                = _mm_setzero_pd();
694             GMX_MM_TRANSPOSE2_PD(G,H);
695             Heps             = _mm_mul_pd(vfeps,H);
696             Fp               = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
697             VV               = _mm_add_pd(Y,_mm_mul_pd(vfeps,Fp));
698             vvdw12           = _mm_mul_pd(c12_00,VV);
699             FF               = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
700             fvdw12           = _mm_mul_pd(c12_00,FF);
701             vvdw             = _mm_add_pd(vvdw12,vvdw6);
702             fvdw             = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
703
704             /* Update potential sum for this i atom from the interaction with this j atom. */
705             velec            = _mm_unpacklo_pd(velec,_mm_setzero_pd());
706             velecsum         = _mm_add_pd(velecsum,velec);
707             vvdw             = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
708             vvdwsum          = _mm_add_pd(vvdwsum,vvdw);
709
710             fscal            = _mm_add_pd(felec,fvdw);
711
712             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
713
714             /* Calculate temporary vectorial force */
715             tx               = _mm_mul_pd(fscal,dx00);
716             ty               = _mm_mul_pd(fscal,dy00);
717             tz               = _mm_mul_pd(fscal,dz00);
718
719             /* Update vectorial force */
720             fix0             = _mm_add_pd(fix0,tx);
721             fiy0             = _mm_add_pd(fiy0,ty);
722             fiz0             = _mm_add_pd(fiz0,tz);
723
724             fjx0             = _mm_add_pd(fjx0,tx);
725             fjy0             = _mm_add_pd(fjy0,ty);
726             fjz0             = _mm_add_pd(fjz0,tz);
727
728             /**************************
729              * CALCULATE INTERACTIONS *
730              **************************/
731
732             /* REACTION-FIELD ELECTROSTATICS */
733             velec            = _mm_mul_pd(qq01,_mm_sub_pd(_mm_add_pd(rinv01,_mm_mul_pd(krf,rsq01)),crf));
734             felec            = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
735
736             /* Update potential sum for this i atom from the interaction with this j atom. */
737             velec            = _mm_unpacklo_pd(velec,_mm_setzero_pd());
738             velecsum         = _mm_add_pd(velecsum,velec);
739
740             fscal            = felec;
741
742             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
743
744             /* Calculate temporary vectorial force */
745             tx               = _mm_mul_pd(fscal,dx01);
746             ty               = _mm_mul_pd(fscal,dy01);
747             tz               = _mm_mul_pd(fscal,dz01);
748
749             /* Update vectorial force */
750             fix0             = _mm_add_pd(fix0,tx);
751             fiy0             = _mm_add_pd(fiy0,ty);
752             fiz0             = _mm_add_pd(fiz0,tz);
753
754             fjx1             = _mm_add_pd(fjx1,tx);
755             fjy1             = _mm_add_pd(fjy1,ty);
756             fjz1             = _mm_add_pd(fjz1,tz);
757
758             /**************************
759              * CALCULATE INTERACTIONS *
760              **************************/
761
762             /* REACTION-FIELD ELECTROSTATICS */
763             velec            = _mm_mul_pd(qq02,_mm_sub_pd(_mm_add_pd(rinv02,_mm_mul_pd(krf,rsq02)),crf));
764             felec            = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
765
766             /* Update potential sum for this i atom from the interaction with this j atom. */
767             velec            = _mm_unpacklo_pd(velec,_mm_setzero_pd());
768             velecsum         = _mm_add_pd(velecsum,velec);
769
770             fscal            = felec;
771
772             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
773
774             /* Calculate temporary vectorial force */
775             tx               = _mm_mul_pd(fscal,dx02);
776             ty               = _mm_mul_pd(fscal,dy02);
777             tz               = _mm_mul_pd(fscal,dz02);
778
779             /* Update vectorial force */
780             fix0             = _mm_add_pd(fix0,tx);
781             fiy0             = _mm_add_pd(fiy0,ty);
782             fiz0             = _mm_add_pd(fiz0,tz);
783
784             fjx2             = _mm_add_pd(fjx2,tx);
785             fjy2             = _mm_add_pd(fjy2,ty);
786             fjz2             = _mm_add_pd(fjz2,tz);
787
788             /**************************
789              * CALCULATE INTERACTIONS *
790              **************************/
791
792             /* REACTION-FIELD ELECTROSTATICS */
793             velec            = _mm_mul_pd(qq10,_mm_sub_pd(_mm_add_pd(rinv10,_mm_mul_pd(krf,rsq10)),crf));
794             felec            = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
795
796             /* Update potential sum for this i atom from the interaction with this j atom. */
797             velec            = _mm_unpacklo_pd(velec,_mm_setzero_pd());
798             velecsum         = _mm_add_pd(velecsum,velec);
799
800             fscal            = felec;
801
802             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
803
804             /* Calculate temporary vectorial force */
805             tx               = _mm_mul_pd(fscal,dx10);
806             ty               = _mm_mul_pd(fscal,dy10);
807             tz               = _mm_mul_pd(fscal,dz10);
808
809             /* Update vectorial force */
810             fix1             = _mm_add_pd(fix1,tx);
811             fiy1             = _mm_add_pd(fiy1,ty);
812             fiz1             = _mm_add_pd(fiz1,tz);
813
814             fjx0             = _mm_add_pd(fjx0,tx);
815             fjy0             = _mm_add_pd(fjy0,ty);
816             fjz0             = _mm_add_pd(fjz0,tz);
817
818             /**************************
819              * CALCULATE INTERACTIONS *
820              **************************/
821
822             /* REACTION-FIELD ELECTROSTATICS */
823             velec            = _mm_mul_pd(qq11,_mm_sub_pd(_mm_add_pd(rinv11,_mm_mul_pd(krf,rsq11)),crf));
824             felec            = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
825
826             /* Update potential sum for this i atom from the interaction with this j atom. */
827             velec            = _mm_unpacklo_pd(velec,_mm_setzero_pd());
828             velecsum         = _mm_add_pd(velecsum,velec);
829
830             fscal            = felec;
831
832             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
833
834             /* Calculate temporary vectorial force */
835             tx               = _mm_mul_pd(fscal,dx11);
836             ty               = _mm_mul_pd(fscal,dy11);
837             tz               = _mm_mul_pd(fscal,dz11);
838
839             /* Update vectorial force */
840             fix1             = _mm_add_pd(fix1,tx);
841             fiy1             = _mm_add_pd(fiy1,ty);
842             fiz1             = _mm_add_pd(fiz1,tz);
843
844             fjx1             = _mm_add_pd(fjx1,tx);
845             fjy1             = _mm_add_pd(fjy1,ty);
846             fjz1             = _mm_add_pd(fjz1,tz);
847
848             /**************************
849              * CALCULATE INTERACTIONS *
850              **************************/
851
852             /* REACTION-FIELD ELECTROSTATICS */
853             velec            = _mm_mul_pd(qq12,_mm_sub_pd(_mm_add_pd(rinv12,_mm_mul_pd(krf,rsq12)),crf));
854             felec            = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
855
856             /* Update potential sum for this i atom from the interaction with this j atom. */
857             velec            = _mm_unpacklo_pd(velec,_mm_setzero_pd());
858             velecsum         = _mm_add_pd(velecsum,velec);
859
860             fscal            = felec;
861
862             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
863
864             /* Calculate temporary vectorial force */
865             tx               = _mm_mul_pd(fscal,dx12);
866             ty               = _mm_mul_pd(fscal,dy12);
867             tz               = _mm_mul_pd(fscal,dz12);
868
869             /* Update vectorial force */
870             fix1             = _mm_add_pd(fix1,tx);
871             fiy1             = _mm_add_pd(fiy1,ty);
872             fiz1             = _mm_add_pd(fiz1,tz);
873
874             fjx2             = _mm_add_pd(fjx2,tx);
875             fjy2             = _mm_add_pd(fjy2,ty);
876             fjz2             = _mm_add_pd(fjz2,tz);
877
878             /**************************
879              * CALCULATE INTERACTIONS *
880              **************************/
881
882             /* REACTION-FIELD ELECTROSTATICS */
883             velec            = _mm_mul_pd(qq20,_mm_sub_pd(_mm_add_pd(rinv20,_mm_mul_pd(krf,rsq20)),crf));
884             felec            = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
885
886             /* Update potential sum for this i atom from the interaction with this j atom. */
887             velec            = _mm_unpacklo_pd(velec,_mm_setzero_pd());
888             velecsum         = _mm_add_pd(velecsum,velec);
889
890             fscal            = felec;
891
892             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
893
894             /* Calculate temporary vectorial force */
895             tx               = _mm_mul_pd(fscal,dx20);
896             ty               = _mm_mul_pd(fscal,dy20);
897             tz               = _mm_mul_pd(fscal,dz20);
898
899             /* Update vectorial force */
900             fix2             = _mm_add_pd(fix2,tx);
901             fiy2             = _mm_add_pd(fiy2,ty);
902             fiz2             = _mm_add_pd(fiz2,tz);
903
904             fjx0             = _mm_add_pd(fjx0,tx);
905             fjy0             = _mm_add_pd(fjy0,ty);
906             fjz0             = _mm_add_pd(fjz0,tz);
907
908             /**************************
909              * CALCULATE INTERACTIONS *
910              **************************/
911
912             /* REACTION-FIELD ELECTROSTATICS */
913             velec            = _mm_mul_pd(qq21,_mm_sub_pd(_mm_add_pd(rinv21,_mm_mul_pd(krf,rsq21)),crf));
914             felec            = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
915
916             /* Update potential sum for this i atom from the interaction with this j atom. */
917             velec            = _mm_unpacklo_pd(velec,_mm_setzero_pd());
918             velecsum         = _mm_add_pd(velecsum,velec);
919
920             fscal            = felec;
921
922             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
923
924             /* Calculate temporary vectorial force */
925             tx               = _mm_mul_pd(fscal,dx21);
926             ty               = _mm_mul_pd(fscal,dy21);
927             tz               = _mm_mul_pd(fscal,dz21);
928
929             /* Update vectorial force */
930             fix2             = _mm_add_pd(fix2,tx);
931             fiy2             = _mm_add_pd(fiy2,ty);
932             fiz2             = _mm_add_pd(fiz2,tz);
933
934             fjx1             = _mm_add_pd(fjx1,tx);
935             fjy1             = _mm_add_pd(fjy1,ty);
936             fjz1             = _mm_add_pd(fjz1,tz);
937
938             /**************************
939              * CALCULATE INTERACTIONS *
940              **************************/
941
942             /* REACTION-FIELD ELECTROSTATICS */
943             velec            = _mm_mul_pd(qq22,_mm_sub_pd(_mm_add_pd(rinv22,_mm_mul_pd(krf,rsq22)),crf));
944             felec            = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
945
946             /* Update potential sum for this i atom from the interaction with this j atom. */
947             velec            = _mm_unpacklo_pd(velec,_mm_setzero_pd());
948             velecsum         = _mm_add_pd(velecsum,velec);
949
950             fscal            = felec;
951
952             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
953
954             /* Calculate temporary vectorial force */
955             tx               = _mm_mul_pd(fscal,dx22);
956             ty               = _mm_mul_pd(fscal,dy22);
957             tz               = _mm_mul_pd(fscal,dz22);
958
959             /* Update vectorial force */
960             fix2             = _mm_add_pd(fix2,tx);
961             fiy2             = _mm_add_pd(fiy2,ty);
962             fiz2             = _mm_add_pd(fiz2,tz);
963
964             fjx2             = _mm_add_pd(fjx2,tx);
965             fjy2             = _mm_add_pd(fjy2,ty);
966             fjz2             = _mm_add_pd(fjz2,tz);
967
968             gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
969
970             /* Inner loop uses 323 flops */
971         }
972
973         /* End of innermost loop */
974
975         gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
976                                               f+i_coord_offset,fshift+i_shift_offset);
977
978         ggid                        = gid[iidx];
979         /* Update potential energies */
980         gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
981         gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
982
983         /* Increment number of inner iterations */
984         inneriter                  += j_index_end - j_index_start;
985
986         /* Outer loop uses 20 flops */
987     }
988
989     /* Increment number of outer iterations */
990     outeriter        += nri;
991
992     /* Update outer/inner flops */
993
994     inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_VF,outeriter*20 + inneriter*323);
995 }
996 /*
997  * Gromacs nonbonded kernel:   nb_kernel_ElecRF_VdwCSTab_GeomW3W3_F_sse2_double
998  * Electrostatics interaction: ReactionField
999  * VdW interaction:            CubicSplineTable
1000  * Geometry:                   Water3-Water3
1001  * Calculate force/pot:        Force
1002  */
1003 void
1004 nb_kernel_ElecRF_VdwCSTab_GeomW3W3_F_sse2_double
1005                     (t_nblist                    * gmx_restrict       nlist,
1006                      rvec                        * gmx_restrict          xx,
1007                      rvec                        * gmx_restrict          ff,
1008                      t_forcerec                  * gmx_restrict          fr,
1009                      t_mdatoms                   * gmx_restrict     mdatoms,
1010                      nb_kernel_data_t gmx_unused * gmx_restrict kernel_data,
1011                      t_nrnb                      * gmx_restrict        nrnb)
1012 {
1013     /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
1014      * just 0 for non-waters.
1015      * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
1016      * jnr indices corresponding to data put in the four positions in the SIMD register.
1017      */
1018     int              i_shift_offset,i_coord_offset,outeriter,inneriter;
1019     int              j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
1020     int              jnrA,jnrB;
1021     int              j_coord_offsetA,j_coord_offsetB;
1022     int              *iinr,*jindex,*jjnr,*shiftidx,*gid;
1023     real             rcutoff_scalar;
1024     real             *shiftvec,*fshift,*x,*f;
1025     __m128d          tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
1026     int              vdwioffset0;
1027     __m128d          ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
1028     int              vdwioffset1;
1029     __m128d          ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
1030     int              vdwioffset2;
1031     __m128d          ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
1032     int              vdwjidx0A,vdwjidx0B;
1033     __m128d          jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
1034     int              vdwjidx1A,vdwjidx1B;
1035     __m128d          jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
1036     int              vdwjidx2A,vdwjidx2B;
1037     __m128d          jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
1038     __m128d          dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
1039     __m128d          dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
1040     __m128d          dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
1041     __m128d          dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
1042     __m128d          dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
1043     __m128d          dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
1044     __m128d          dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
1045     __m128d          dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
1046     __m128d          dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
1047     __m128d          velec,felec,velecsum,facel,crf,krf,krf2;
1048     real             *charge;
1049     int              nvdwtype;
1050     __m128d          rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
1051     int              *vdwtype;
1052     real             *vdwparam;
1053     __m128d          one_sixth   = _mm_set1_pd(1.0/6.0);
1054     __m128d          one_twelfth = _mm_set1_pd(1.0/12.0);
1055     __m128i          vfitab;
1056     __m128i          ifour       = _mm_set1_epi32(4);
1057     __m128d          rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
1058     real             *vftab;
1059     __m128d          dummy_mask,cutoff_mask;
1060     __m128d          signbit   = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
1061     __m128d          one     = _mm_set1_pd(1.0);
1062     __m128d          two     = _mm_set1_pd(2.0);
1063     x                = xx[0];
1064     f                = ff[0];
1065
1066     nri              = nlist->nri;
1067     iinr             = nlist->iinr;
1068     jindex           = nlist->jindex;
1069     jjnr             = nlist->jjnr;
1070     shiftidx         = nlist->shift;
1071     gid              = nlist->gid;
1072     shiftvec         = fr->shift_vec[0];
1073     fshift           = fr->fshift[0];
1074     facel            = _mm_set1_pd(fr->epsfac);
1075     charge           = mdatoms->chargeA;
1076     krf              = _mm_set1_pd(fr->ic->k_rf);
1077     krf2             = _mm_set1_pd(fr->ic->k_rf*2.0);
1078     crf              = _mm_set1_pd(fr->ic->c_rf);
1079     nvdwtype         = fr->ntype;
1080     vdwparam         = fr->nbfp;
1081     vdwtype          = mdatoms->typeA;
1082
1083     vftab            = kernel_data->table_vdw->data;
1084     vftabscale       = _mm_set1_pd(kernel_data->table_vdw->scale);
1085
1086     /* Setup water-specific parameters */
1087     inr              = nlist->iinr[0];
1088     iq0              = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
1089     iq1              = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
1090     iq2              = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
1091     vdwioffset0      = 2*nvdwtype*vdwtype[inr+0];
1092
1093     jq0              = _mm_set1_pd(charge[inr+0]);
1094     jq1              = _mm_set1_pd(charge[inr+1]);
1095     jq2              = _mm_set1_pd(charge[inr+2]);
1096     vdwjidx0A        = 2*vdwtype[inr+0];
1097     qq00             = _mm_mul_pd(iq0,jq0);
1098     c6_00            = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
1099     c12_00           = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
1100     qq01             = _mm_mul_pd(iq0,jq1);
1101     qq02             = _mm_mul_pd(iq0,jq2);
1102     qq10             = _mm_mul_pd(iq1,jq0);
1103     qq11             = _mm_mul_pd(iq1,jq1);
1104     qq12             = _mm_mul_pd(iq1,jq2);
1105     qq20             = _mm_mul_pd(iq2,jq0);
1106     qq21             = _mm_mul_pd(iq2,jq1);
1107     qq22             = _mm_mul_pd(iq2,jq2);
1108
1109     /* Avoid stupid compiler warnings */
1110     jnrA = jnrB = 0;
1111     j_coord_offsetA = 0;
1112     j_coord_offsetB = 0;
1113
1114     outeriter        = 0;
1115     inneriter        = 0;
1116
1117     /* Start outer loop over neighborlists */
1118     for(iidx=0; iidx<nri; iidx++)
1119     {
1120         /* Load shift vector for this list */
1121         i_shift_offset   = DIM*shiftidx[iidx];
1122
1123         /* Load limits for loop over neighbors */
1124         j_index_start    = jindex[iidx];
1125         j_index_end      = jindex[iidx+1];
1126
1127         /* Get outer coordinate index */
1128         inr              = iinr[iidx];
1129         i_coord_offset   = DIM*inr;
1130
1131         /* Load i particle coords and add shift vector */
1132         gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
1133                                                  &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
1134
1135         fix0             = _mm_setzero_pd();
1136         fiy0             = _mm_setzero_pd();
1137         fiz0             = _mm_setzero_pd();
1138         fix1             = _mm_setzero_pd();
1139         fiy1             = _mm_setzero_pd();
1140         fiz1             = _mm_setzero_pd();
1141         fix2             = _mm_setzero_pd();
1142         fiy2             = _mm_setzero_pd();
1143         fiz2             = _mm_setzero_pd();
1144
1145         /* Start inner kernel loop */
1146         for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
1147         {
1148
1149             /* Get j neighbor index, and coordinate index */
1150             jnrA             = jjnr[jidx];
1151             jnrB             = jjnr[jidx+1];
1152             j_coord_offsetA  = DIM*jnrA;
1153             j_coord_offsetB  = DIM*jnrB;
1154
1155             /* load j atom coordinates */
1156             gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
1157                                               &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
1158
1159             /* Calculate displacement vector */
1160             dx00             = _mm_sub_pd(ix0,jx0);
1161             dy00             = _mm_sub_pd(iy0,jy0);
1162             dz00             = _mm_sub_pd(iz0,jz0);
1163             dx01             = _mm_sub_pd(ix0,jx1);
1164             dy01             = _mm_sub_pd(iy0,jy1);
1165             dz01             = _mm_sub_pd(iz0,jz1);
1166             dx02             = _mm_sub_pd(ix0,jx2);
1167             dy02             = _mm_sub_pd(iy0,jy2);
1168             dz02             = _mm_sub_pd(iz0,jz2);
1169             dx10             = _mm_sub_pd(ix1,jx0);
1170             dy10             = _mm_sub_pd(iy1,jy0);
1171             dz10             = _mm_sub_pd(iz1,jz0);
1172             dx11             = _mm_sub_pd(ix1,jx1);
1173             dy11             = _mm_sub_pd(iy1,jy1);
1174             dz11             = _mm_sub_pd(iz1,jz1);
1175             dx12             = _mm_sub_pd(ix1,jx2);
1176             dy12             = _mm_sub_pd(iy1,jy2);
1177             dz12             = _mm_sub_pd(iz1,jz2);
1178             dx20             = _mm_sub_pd(ix2,jx0);
1179             dy20             = _mm_sub_pd(iy2,jy0);
1180             dz20             = _mm_sub_pd(iz2,jz0);
1181             dx21             = _mm_sub_pd(ix2,jx1);
1182             dy21             = _mm_sub_pd(iy2,jy1);
1183             dz21             = _mm_sub_pd(iz2,jz1);
1184             dx22             = _mm_sub_pd(ix2,jx2);
1185             dy22             = _mm_sub_pd(iy2,jy2);
1186             dz22             = _mm_sub_pd(iz2,jz2);
1187
1188             /* Calculate squared distance and things based on it */
1189             rsq00            = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
1190             rsq01            = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
1191             rsq02            = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
1192             rsq10            = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
1193             rsq11            = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
1194             rsq12            = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
1195             rsq20            = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
1196             rsq21            = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
1197             rsq22            = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
1198
1199             rinv00           = gmx_mm_invsqrt_pd(rsq00);
1200             rinv01           = gmx_mm_invsqrt_pd(rsq01);
1201             rinv02           = gmx_mm_invsqrt_pd(rsq02);
1202             rinv10           = gmx_mm_invsqrt_pd(rsq10);
1203             rinv11           = gmx_mm_invsqrt_pd(rsq11);
1204             rinv12           = gmx_mm_invsqrt_pd(rsq12);
1205             rinv20           = gmx_mm_invsqrt_pd(rsq20);
1206             rinv21           = gmx_mm_invsqrt_pd(rsq21);
1207             rinv22           = gmx_mm_invsqrt_pd(rsq22);
1208
1209             rinvsq00         = _mm_mul_pd(rinv00,rinv00);
1210             rinvsq01         = _mm_mul_pd(rinv01,rinv01);
1211             rinvsq02         = _mm_mul_pd(rinv02,rinv02);
1212             rinvsq10         = _mm_mul_pd(rinv10,rinv10);
1213             rinvsq11         = _mm_mul_pd(rinv11,rinv11);
1214             rinvsq12         = _mm_mul_pd(rinv12,rinv12);
1215             rinvsq20         = _mm_mul_pd(rinv20,rinv20);
1216             rinvsq21         = _mm_mul_pd(rinv21,rinv21);
1217             rinvsq22         = _mm_mul_pd(rinv22,rinv22);
1218
1219             fjx0             = _mm_setzero_pd();
1220             fjy0             = _mm_setzero_pd();
1221             fjz0             = _mm_setzero_pd();
1222             fjx1             = _mm_setzero_pd();
1223             fjy1             = _mm_setzero_pd();
1224             fjz1             = _mm_setzero_pd();
1225             fjx2             = _mm_setzero_pd();
1226             fjy2             = _mm_setzero_pd();
1227             fjz2             = _mm_setzero_pd();
1228
1229             /**************************
1230              * CALCULATE INTERACTIONS *
1231              **************************/
1232
1233             r00              = _mm_mul_pd(rsq00,rinv00);
1234
1235             /* Calculate table index by multiplying r with table scale and truncate to integer */
1236             rt               = _mm_mul_pd(r00,vftabscale);
1237             vfitab           = _mm_cvttpd_epi32(rt);
1238             vfeps            = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
1239             vfitab           = _mm_slli_epi32(vfitab,3);
1240
1241             /* REACTION-FIELD ELECTROSTATICS */
1242             felec            = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
1243
1244             /* CUBIC SPLINE TABLE DISPERSION */
1245             Y                = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
1246             F                = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
1247             GMX_MM_TRANSPOSE2_PD(Y,F);
1248             G                = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
1249             H                = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
1250             GMX_MM_TRANSPOSE2_PD(G,H);
1251             Heps             = _mm_mul_pd(vfeps,H);
1252             Fp               = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
1253             FF               = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
1254             fvdw6            = _mm_mul_pd(c6_00,FF);
1255
1256             /* CUBIC SPLINE TABLE REPULSION */
1257             vfitab           = _mm_add_epi32(vfitab,ifour);
1258             Y                = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
1259             F                = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) );
1260             GMX_MM_TRANSPOSE2_PD(Y,F);
1261             G                = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
1262             H                = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,1) +2);
1263             GMX_MM_TRANSPOSE2_PD(G,H);
1264             Heps             = _mm_mul_pd(vfeps,H);
1265             Fp               = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
1266             FF               = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
1267             fvdw12           = _mm_mul_pd(c12_00,FF);
1268             fvdw             = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
1269
1270             fscal            = _mm_add_pd(felec,fvdw);
1271
1272             /* Calculate temporary vectorial force */
1273             tx               = _mm_mul_pd(fscal,dx00);
1274             ty               = _mm_mul_pd(fscal,dy00);
1275             tz               = _mm_mul_pd(fscal,dz00);
1276
1277             /* Update vectorial force */
1278             fix0             = _mm_add_pd(fix0,tx);
1279             fiy0             = _mm_add_pd(fiy0,ty);
1280             fiz0             = _mm_add_pd(fiz0,tz);
1281
1282             fjx0             = _mm_add_pd(fjx0,tx);
1283             fjy0             = _mm_add_pd(fjy0,ty);
1284             fjz0             = _mm_add_pd(fjz0,tz);
1285
1286             /**************************
1287              * CALCULATE INTERACTIONS *
1288              **************************/
1289
1290             /* REACTION-FIELD ELECTROSTATICS */
1291             felec            = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
1292
1293             fscal            = felec;
1294
1295             /* Calculate temporary vectorial force */
1296             tx               = _mm_mul_pd(fscal,dx01);
1297             ty               = _mm_mul_pd(fscal,dy01);
1298             tz               = _mm_mul_pd(fscal,dz01);
1299
1300             /* Update vectorial force */
1301             fix0             = _mm_add_pd(fix0,tx);
1302             fiy0             = _mm_add_pd(fiy0,ty);
1303             fiz0             = _mm_add_pd(fiz0,tz);
1304
1305             fjx1             = _mm_add_pd(fjx1,tx);
1306             fjy1             = _mm_add_pd(fjy1,ty);
1307             fjz1             = _mm_add_pd(fjz1,tz);
1308
1309             /**************************
1310              * CALCULATE INTERACTIONS *
1311              **************************/
1312
1313             /* REACTION-FIELD ELECTROSTATICS */
1314             felec            = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
1315
1316             fscal            = felec;
1317
1318             /* Calculate temporary vectorial force */
1319             tx               = _mm_mul_pd(fscal,dx02);
1320             ty               = _mm_mul_pd(fscal,dy02);
1321             tz               = _mm_mul_pd(fscal,dz02);
1322
1323             /* Update vectorial force */
1324             fix0             = _mm_add_pd(fix0,tx);
1325             fiy0             = _mm_add_pd(fiy0,ty);
1326             fiz0             = _mm_add_pd(fiz0,tz);
1327
1328             fjx2             = _mm_add_pd(fjx2,tx);
1329             fjy2             = _mm_add_pd(fjy2,ty);
1330             fjz2             = _mm_add_pd(fjz2,tz);
1331
1332             /**************************
1333              * CALCULATE INTERACTIONS *
1334              **************************/
1335
1336             /* REACTION-FIELD ELECTROSTATICS */
1337             felec            = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
1338
1339             fscal            = felec;
1340
1341             /* Calculate temporary vectorial force */
1342             tx               = _mm_mul_pd(fscal,dx10);
1343             ty               = _mm_mul_pd(fscal,dy10);
1344             tz               = _mm_mul_pd(fscal,dz10);
1345
1346             /* Update vectorial force */
1347             fix1             = _mm_add_pd(fix1,tx);
1348             fiy1             = _mm_add_pd(fiy1,ty);
1349             fiz1             = _mm_add_pd(fiz1,tz);
1350
1351             fjx0             = _mm_add_pd(fjx0,tx);
1352             fjy0             = _mm_add_pd(fjy0,ty);
1353             fjz0             = _mm_add_pd(fjz0,tz);
1354
1355             /**************************
1356              * CALCULATE INTERACTIONS *
1357              **************************/
1358
1359             /* REACTION-FIELD ELECTROSTATICS */
1360             felec            = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
1361
1362             fscal            = felec;
1363
1364             /* Calculate temporary vectorial force */
1365             tx               = _mm_mul_pd(fscal,dx11);
1366             ty               = _mm_mul_pd(fscal,dy11);
1367             tz               = _mm_mul_pd(fscal,dz11);
1368
1369             /* Update vectorial force */
1370             fix1             = _mm_add_pd(fix1,tx);
1371             fiy1             = _mm_add_pd(fiy1,ty);
1372             fiz1             = _mm_add_pd(fiz1,tz);
1373
1374             fjx1             = _mm_add_pd(fjx1,tx);
1375             fjy1             = _mm_add_pd(fjy1,ty);
1376             fjz1             = _mm_add_pd(fjz1,tz);
1377
1378             /**************************
1379              * CALCULATE INTERACTIONS *
1380              **************************/
1381
1382             /* REACTION-FIELD ELECTROSTATICS */
1383             felec            = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
1384
1385             fscal            = felec;
1386
1387             /* Calculate temporary vectorial force */
1388             tx               = _mm_mul_pd(fscal,dx12);
1389             ty               = _mm_mul_pd(fscal,dy12);
1390             tz               = _mm_mul_pd(fscal,dz12);
1391
1392             /* Update vectorial force */
1393             fix1             = _mm_add_pd(fix1,tx);
1394             fiy1             = _mm_add_pd(fiy1,ty);
1395             fiz1             = _mm_add_pd(fiz1,tz);
1396
1397             fjx2             = _mm_add_pd(fjx2,tx);
1398             fjy2             = _mm_add_pd(fjy2,ty);
1399             fjz2             = _mm_add_pd(fjz2,tz);
1400
1401             /**************************
1402              * CALCULATE INTERACTIONS *
1403              **************************/
1404
1405             /* REACTION-FIELD ELECTROSTATICS */
1406             felec            = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
1407
1408             fscal            = felec;
1409
1410             /* Calculate temporary vectorial force */
1411             tx               = _mm_mul_pd(fscal,dx20);
1412             ty               = _mm_mul_pd(fscal,dy20);
1413             tz               = _mm_mul_pd(fscal,dz20);
1414
1415             /* Update vectorial force */
1416             fix2             = _mm_add_pd(fix2,tx);
1417             fiy2             = _mm_add_pd(fiy2,ty);
1418             fiz2             = _mm_add_pd(fiz2,tz);
1419
1420             fjx0             = _mm_add_pd(fjx0,tx);
1421             fjy0             = _mm_add_pd(fjy0,ty);
1422             fjz0             = _mm_add_pd(fjz0,tz);
1423
1424             /**************************
1425              * CALCULATE INTERACTIONS *
1426              **************************/
1427
1428             /* REACTION-FIELD ELECTROSTATICS */
1429             felec            = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
1430
1431             fscal            = felec;
1432
1433             /* Calculate temporary vectorial force */
1434             tx               = _mm_mul_pd(fscal,dx21);
1435             ty               = _mm_mul_pd(fscal,dy21);
1436             tz               = _mm_mul_pd(fscal,dz21);
1437
1438             /* Update vectorial force */
1439             fix2             = _mm_add_pd(fix2,tx);
1440             fiy2             = _mm_add_pd(fiy2,ty);
1441             fiz2             = _mm_add_pd(fiz2,tz);
1442
1443             fjx1             = _mm_add_pd(fjx1,tx);
1444             fjy1             = _mm_add_pd(fjy1,ty);
1445             fjz1             = _mm_add_pd(fjz1,tz);
1446
1447             /**************************
1448              * CALCULATE INTERACTIONS *
1449              **************************/
1450
1451             /* REACTION-FIELD ELECTROSTATICS */
1452             felec            = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
1453
1454             fscal            = felec;
1455
1456             /* Calculate temporary vectorial force */
1457             tx               = _mm_mul_pd(fscal,dx22);
1458             ty               = _mm_mul_pd(fscal,dy22);
1459             tz               = _mm_mul_pd(fscal,dz22);
1460
1461             /* Update vectorial force */
1462             fix2             = _mm_add_pd(fix2,tx);
1463             fiy2             = _mm_add_pd(fiy2,ty);
1464             fiz2             = _mm_add_pd(fiz2,tz);
1465
1466             fjx2             = _mm_add_pd(fjx2,tx);
1467             fjy2             = _mm_add_pd(fjy2,ty);
1468             fjz2             = _mm_add_pd(fjz2,tz);
1469
1470             gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
1471
1472             /* Inner loop uses 270 flops */
1473         }
1474
1475         if(jidx<j_index_end)
1476         {
1477
1478             jnrA             = jjnr[jidx];
1479             j_coord_offsetA  = DIM*jnrA;
1480
1481             /* load j atom coordinates */
1482             gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
1483                                               &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
1484
1485             /* Calculate displacement vector */
1486             dx00             = _mm_sub_pd(ix0,jx0);
1487             dy00             = _mm_sub_pd(iy0,jy0);
1488             dz00             = _mm_sub_pd(iz0,jz0);
1489             dx01             = _mm_sub_pd(ix0,jx1);
1490             dy01             = _mm_sub_pd(iy0,jy1);
1491             dz01             = _mm_sub_pd(iz0,jz1);
1492             dx02             = _mm_sub_pd(ix0,jx2);
1493             dy02             = _mm_sub_pd(iy0,jy2);
1494             dz02             = _mm_sub_pd(iz0,jz2);
1495             dx10             = _mm_sub_pd(ix1,jx0);
1496             dy10             = _mm_sub_pd(iy1,jy0);
1497             dz10             = _mm_sub_pd(iz1,jz0);
1498             dx11             = _mm_sub_pd(ix1,jx1);
1499             dy11             = _mm_sub_pd(iy1,jy1);
1500             dz11             = _mm_sub_pd(iz1,jz1);
1501             dx12             = _mm_sub_pd(ix1,jx2);
1502             dy12             = _mm_sub_pd(iy1,jy2);
1503             dz12             = _mm_sub_pd(iz1,jz2);
1504             dx20             = _mm_sub_pd(ix2,jx0);
1505             dy20             = _mm_sub_pd(iy2,jy0);
1506             dz20             = _mm_sub_pd(iz2,jz0);
1507             dx21             = _mm_sub_pd(ix2,jx1);
1508             dy21             = _mm_sub_pd(iy2,jy1);
1509             dz21             = _mm_sub_pd(iz2,jz1);
1510             dx22             = _mm_sub_pd(ix2,jx2);
1511             dy22             = _mm_sub_pd(iy2,jy2);
1512             dz22             = _mm_sub_pd(iz2,jz2);
1513
1514             /* Calculate squared distance and things based on it */
1515             rsq00            = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
1516             rsq01            = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
1517             rsq02            = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
1518             rsq10            = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
1519             rsq11            = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
1520             rsq12            = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
1521             rsq20            = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
1522             rsq21            = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
1523             rsq22            = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
1524
1525             rinv00           = gmx_mm_invsqrt_pd(rsq00);
1526             rinv01           = gmx_mm_invsqrt_pd(rsq01);
1527             rinv02           = gmx_mm_invsqrt_pd(rsq02);
1528             rinv10           = gmx_mm_invsqrt_pd(rsq10);
1529             rinv11           = gmx_mm_invsqrt_pd(rsq11);
1530             rinv12           = gmx_mm_invsqrt_pd(rsq12);
1531             rinv20           = gmx_mm_invsqrt_pd(rsq20);
1532             rinv21           = gmx_mm_invsqrt_pd(rsq21);
1533             rinv22           = gmx_mm_invsqrt_pd(rsq22);
1534
1535             rinvsq00         = _mm_mul_pd(rinv00,rinv00);
1536             rinvsq01         = _mm_mul_pd(rinv01,rinv01);
1537             rinvsq02         = _mm_mul_pd(rinv02,rinv02);
1538             rinvsq10         = _mm_mul_pd(rinv10,rinv10);
1539             rinvsq11         = _mm_mul_pd(rinv11,rinv11);
1540             rinvsq12         = _mm_mul_pd(rinv12,rinv12);
1541             rinvsq20         = _mm_mul_pd(rinv20,rinv20);
1542             rinvsq21         = _mm_mul_pd(rinv21,rinv21);
1543             rinvsq22         = _mm_mul_pd(rinv22,rinv22);
1544
1545             fjx0             = _mm_setzero_pd();
1546             fjy0             = _mm_setzero_pd();
1547             fjz0             = _mm_setzero_pd();
1548             fjx1             = _mm_setzero_pd();
1549             fjy1             = _mm_setzero_pd();
1550             fjz1             = _mm_setzero_pd();
1551             fjx2             = _mm_setzero_pd();
1552             fjy2             = _mm_setzero_pd();
1553             fjz2             = _mm_setzero_pd();
1554
1555             /**************************
1556              * CALCULATE INTERACTIONS *
1557              **************************/
1558
1559             r00              = _mm_mul_pd(rsq00,rinv00);
1560
1561             /* Calculate table index by multiplying r with table scale and truncate to integer */
1562             rt               = _mm_mul_pd(r00,vftabscale);
1563             vfitab           = _mm_cvttpd_epi32(rt);
1564             vfeps            = _mm_sub_pd(rt,_mm_cvtepi32_pd(vfitab));
1565             vfitab           = _mm_slli_epi32(vfitab,3);
1566
1567             /* REACTION-FIELD ELECTROSTATICS */
1568             felec            = _mm_mul_pd(qq00,_mm_sub_pd(_mm_mul_pd(rinv00,rinvsq00),krf2));
1569
1570             /* CUBIC SPLINE TABLE DISPERSION */
1571             Y                = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
1572             F                = _mm_setzero_pd();
1573             GMX_MM_TRANSPOSE2_PD(Y,F);
1574             G                = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
1575             H                = _mm_setzero_pd();
1576             GMX_MM_TRANSPOSE2_PD(G,H);
1577             Heps             = _mm_mul_pd(vfeps,H);
1578             Fp               = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
1579             FF               = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
1580             fvdw6            = _mm_mul_pd(c6_00,FF);
1581
1582             /* CUBIC SPLINE TABLE REPULSION */
1583             vfitab           = _mm_add_epi32(vfitab,ifour);
1584             Y                = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) );
1585             F                = _mm_setzero_pd();
1586             GMX_MM_TRANSPOSE2_PD(Y,F);
1587             G                = _mm_load_pd( vftab + gmx_mm_extract_epi32(vfitab,0) +2);
1588             H                = _mm_setzero_pd();
1589             GMX_MM_TRANSPOSE2_PD(G,H);
1590             Heps             = _mm_mul_pd(vfeps,H);
1591             Fp               = _mm_add_pd(F,_mm_mul_pd(vfeps,_mm_add_pd(G,Heps)));
1592             FF               = _mm_add_pd(Fp,_mm_mul_pd(vfeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
1593             fvdw12           = _mm_mul_pd(c12_00,FF);
1594             fvdw             = _mm_xor_pd(signbit,_mm_mul_pd(_mm_add_pd(fvdw6,fvdw12),_mm_mul_pd(vftabscale,rinv00)));
1595
1596             fscal            = _mm_add_pd(felec,fvdw);
1597
1598             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
1599
1600             /* Calculate temporary vectorial force */
1601             tx               = _mm_mul_pd(fscal,dx00);
1602             ty               = _mm_mul_pd(fscal,dy00);
1603             tz               = _mm_mul_pd(fscal,dz00);
1604
1605             /* Update vectorial force */
1606             fix0             = _mm_add_pd(fix0,tx);
1607             fiy0             = _mm_add_pd(fiy0,ty);
1608             fiz0             = _mm_add_pd(fiz0,tz);
1609
1610             fjx0             = _mm_add_pd(fjx0,tx);
1611             fjy0             = _mm_add_pd(fjy0,ty);
1612             fjz0             = _mm_add_pd(fjz0,tz);
1613
1614             /**************************
1615              * CALCULATE INTERACTIONS *
1616              **************************/
1617
1618             /* REACTION-FIELD ELECTROSTATICS */
1619             felec            = _mm_mul_pd(qq01,_mm_sub_pd(_mm_mul_pd(rinv01,rinvsq01),krf2));
1620
1621             fscal            = felec;
1622
1623             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
1624
1625             /* Calculate temporary vectorial force */
1626             tx               = _mm_mul_pd(fscal,dx01);
1627             ty               = _mm_mul_pd(fscal,dy01);
1628             tz               = _mm_mul_pd(fscal,dz01);
1629
1630             /* Update vectorial force */
1631             fix0             = _mm_add_pd(fix0,tx);
1632             fiy0             = _mm_add_pd(fiy0,ty);
1633             fiz0             = _mm_add_pd(fiz0,tz);
1634
1635             fjx1             = _mm_add_pd(fjx1,tx);
1636             fjy1             = _mm_add_pd(fjy1,ty);
1637             fjz1             = _mm_add_pd(fjz1,tz);
1638
1639             /**************************
1640              * CALCULATE INTERACTIONS *
1641              **************************/
1642
1643             /* REACTION-FIELD ELECTROSTATICS */
1644             felec            = _mm_mul_pd(qq02,_mm_sub_pd(_mm_mul_pd(rinv02,rinvsq02),krf2));
1645
1646             fscal            = felec;
1647
1648             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
1649
1650             /* Calculate temporary vectorial force */
1651             tx               = _mm_mul_pd(fscal,dx02);
1652             ty               = _mm_mul_pd(fscal,dy02);
1653             tz               = _mm_mul_pd(fscal,dz02);
1654
1655             /* Update vectorial force */
1656             fix0             = _mm_add_pd(fix0,tx);
1657             fiy0             = _mm_add_pd(fiy0,ty);
1658             fiz0             = _mm_add_pd(fiz0,tz);
1659
1660             fjx2             = _mm_add_pd(fjx2,tx);
1661             fjy2             = _mm_add_pd(fjy2,ty);
1662             fjz2             = _mm_add_pd(fjz2,tz);
1663
1664             /**************************
1665              * CALCULATE INTERACTIONS *
1666              **************************/
1667
1668             /* REACTION-FIELD ELECTROSTATICS */
1669             felec            = _mm_mul_pd(qq10,_mm_sub_pd(_mm_mul_pd(rinv10,rinvsq10),krf2));
1670
1671             fscal            = felec;
1672
1673             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
1674
1675             /* Calculate temporary vectorial force */
1676             tx               = _mm_mul_pd(fscal,dx10);
1677             ty               = _mm_mul_pd(fscal,dy10);
1678             tz               = _mm_mul_pd(fscal,dz10);
1679
1680             /* Update vectorial force */
1681             fix1             = _mm_add_pd(fix1,tx);
1682             fiy1             = _mm_add_pd(fiy1,ty);
1683             fiz1             = _mm_add_pd(fiz1,tz);
1684
1685             fjx0             = _mm_add_pd(fjx0,tx);
1686             fjy0             = _mm_add_pd(fjy0,ty);
1687             fjz0             = _mm_add_pd(fjz0,tz);
1688
1689             /**************************
1690              * CALCULATE INTERACTIONS *
1691              **************************/
1692
1693             /* REACTION-FIELD ELECTROSTATICS */
1694             felec            = _mm_mul_pd(qq11,_mm_sub_pd(_mm_mul_pd(rinv11,rinvsq11),krf2));
1695
1696             fscal            = felec;
1697
1698             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
1699
1700             /* Calculate temporary vectorial force */
1701             tx               = _mm_mul_pd(fscal,dx11);
1702             ty               = _mm_mul_pd(fscal,dy11);
1703             tz               = _mm_mul_pd(fscal,dz11);
1704
1705             /* Update vectorial force */
1706             fix1             = _mm_add_pd(fix1,tx);
1707             fiy1             = _mm_add_pd(fiy1,ty);
1708             fiz1             = _mm_add_pd(fiz1,tz);
1709
1710             fjx1             = _mm_add_pd(fjx1,tx);
1711             fjy1             = _mm_add_pd(fjy1,ty);
1712             fjz1             = _mm_add_pd(fjz1,tz);
1713
1714             /**************************
1715              * CALCULATE INTERACTIONS *
1716              **************************/
1717
1718             /* REACTION-FIELD ELECTROSTATICS */
1719             felec            = _mm_mul_pd(qq12,_mm_sub_pd(_mm_mul_pd(rinv12,rinvsq12),krf2));
1720
1721             fscal            = felec;
1722
1723             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
1724
1725             /* Calculate temporary vectorial force */
1726             tx               = _mm_mul_pd(fscal,dx12);
1727             ty               = _mm_mul_pd(fscal,dy12);
1728             tz               = _mm_mul_pd(fscal,dz12);
1729
1730             /* Update vectorial force */
1731             fix1             = _mm_add_pd(fix1,tx);
1732             fiy1             = _mm_add_pd(fiy1,ty);
1733             fiz1             = _mm_add_pd(fiz1,tz);
1734
1735             fjx2             = _mm_add_pd(fjx2,tx);
1736             fjy2             = _mm_add_pd(fjy2,ty);
1737             fjz2             = _mm_add_pd(fjz2,tz);
1738
1739             /**************************
1740              * CALCULATE INTERACTIONS *
1741              **************************/
1742
1743             /* REACTION-FIELD ELECTROSTATICS */
1744             felec            = _mm_mul_pd(qq20,_mm_sub_pd(_mm_mul_pd(rinv20,rinvsq20),krf2));
1745
1746             fscal            = felec;
1747
1748             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
1749
1750             /* Calculate temporary vectorial force */
1751             tx               = _mm_mul_pd(fscal,dx20);
1752             ty               = _mm_mul_pd(fscal,dy20);
1753             tz               = _mm_mul_pd(fscal,dz20);
1754
1755             /* Update vectorial force */
1756             fix2             = _mm_add_pd(fix2,tx);
1757             fiy2             = _mm_add_pd(fiy2,ty);
1758             fiz2             = _mm_add_pd(fiz2,tz);
1759
1760             fjx0             = _mm_add_pd(fjx0,tx);
1761             fjy0             = _mm_add_pd(fjy0,ty);
1762             fjz0             = _mm_add_pd(fjz0,tz);
1763
1764             /**************************
1765              * CALCULATE INTERACTIONS *
1766              **************************/
1767
1768             /* REACTION-FIELD ELECTROSTATICS */
1769             felec            = _mm_mul_pd(qq21,_mm_sub_pd(_mm_mul_pd(rinv21,rinvsq21),krf2));
1770
1771             fscal            = felec;
1772
1773             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
1774
1775             /* Calculate temporary vectorial force */
1776             tx               = _mm_mul_pd(fscal,dx21);
1777             ty               = _mm_mul_pd(fscal,dy21);
1778             tz               = _mm_mul_pd(fscal,dz21);
1779
1780             /* Update vectorial force */
1781             fix2             = _mm_add_pd(fix2,tx);
1782             fiy2             = _mm_add_pd(fiy2,ty);
1783             fiz2             = _mm_add_pd(fiz2,tz);
1784
1785             fjx1             = _mm_add_pd(fjx1,tx);
1786             fjy1             = _mm_add_pd(fjy1,ty);
1787             fjz1             = _mm_add_pd(fjz1,tz);
1788
1789             /**************************
1790              * CALCULATE INTERACTIONS *
1791              **************************/
1792
1793             /* REACTION-FIELD ELECTROSTATICS */
1794             felec            = _mm_mul_pd(qq22,_mm_sub_pd(_mm_mul_pd(rinv22,rinvsq22),krf2));
1795
1796             fscal            = felec;
1797
1798             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
1799
1800             /* Calculate temporary vectorial force */
1801             tx               = _mm_mul_pd(fscal,dx22);
1802             ty               = _mm_mul_pd(fscal,dy22);
1803             tz               = _mm_mul_pd(fscal,dz22);
1804
1805             /* Update vectorial force */
1806             fix2             = _mm_add_pd(fix2,tx);
1807             fiy2             = _mm_add_pd(fiy2,ty);
1808             fiz2             = _mm_add_pd(fiz2,tz);
1809
1810             fjx2             = _mm_add_pd(fjx2,tx);
1811             fjy2             = _mm_add_pd(fjy2,ty);
1812             fjz2             = _mm_add_pd(fjz2,tz);
1813
1814             gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
1815
1816             /* Inner loop uses 270 flops */
1817         }
1818
1819         /* End of innermost loop */
1820
1821         gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
1822                                               f+i_coord_offset,fshift+i_shift_offset);
1823
1824         /* Increment number of inner iterations */
1825         inneriter                  += j_index_end - j_index_start;
1826
1827         /* Outer loop uses 18 flops */
1828     }
1829
1830     /* Increment number of outer iterations */
1831     outeriter        += nri;
1832
1833     /* Update outer/inner flops */
1834
1835     inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_F,outeriter*18 + inneriter*270);
1836 }