Merge release-4-6 into master
[alexxy/gromacs.git] / src / gromacs / gmxlib / nonbonded / nb_kernel_avx_256_single / nb_kernel_ElecEw_VdwCSTab_GeomW4W4_avx_256_single.c
1 /*
2  * Note: this file was generated by the Gromacs avx_256_single kernel generator.
3  *
4  *                This source code is part of
5  *
6  *                 G   R   O   M   A   C   S
7  *
8  * Copyright (c) 2001-2012, The GROMACS Development Team
9  *
10  * Gromacs is a library for molecular simulation and trajectory analysis,
11  * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
12  * a full list of developers and information, check out http://www.gromacs.org
13  *
14  * This program is free software; you can redistribute it and/or modify it under
15  * the terms of the GNU Lesser General Public License as published by the Free
16  * Software Foundation; either version 2 of the License, or (at your option) any
17  * later version.
18  *
19  * To help fund GROMACS development, we humbly ask that you cite
20  * the papers people have written on it - you can find them on the website.
21  */
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <math.h>
27
28 #include "../nb_kernel.h"
29 #include "types/simple.h"
30 #include "vec.h"
31 #include "nrnb.h"
32
33 #include "gmx_math_x86_avx_256_single.h"
34 #include "kernelutil_x86_avx_256_single.h"
35
36 /*
37  * Gromacs nonbonded kernel:   nb_kernel_ElecEw_VdwCSTab_GeomW4W4_VF_avx_256_single
38  * Electrostatics interaction: Ewald
39  * VdW interaction:            CubicSplineTable
40  * Geometry:                   Water4-Water4
41  * Calculate force/pot:        PotentialAndForce
42  */
43 void
44 nb_kernel_ElecEw_VdwCSTab_GeomW4W4_VF_avx_256_single
45                     (t_nblist * gmx_restrict                nlist,
46                      rvec * gmx_restrict                    xx,
47                      rvec * gmx_restrict                    ff,
48                      t_forcerec * gmx_restrict              fr,
49                      t_mdatoms * gmx_restrict               mdatoms,
50                      nb_kernel_data_t * gmx_restrict        kernel_data,
51                      t_nrnb * gmx_restrict                  nrnb)
52 {
53     /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or 
54      * just 0 for non-waters.
55      * Suffixes A,B,C,D,E,F,G,H refer to j loop unrolling done with AVX, e.g. for the eight different
56      * jnr indices corresponding to data put in the four positions in the SIMD register.
57      */
58     int              i_shift_offset,i_coord_offset,outeriter,inneriter;
59     int              j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
60     int              jnrA,jnrB,jnrC,jnrD;
61     int              jnrE,jnrF,jnrG,jnrH;
62     int              jnrlistA,jnrlistB,jnrlistC,jnrlistD;
63     int              jnrlistE,jnrlistF,jnrlistG,jnrlistH;
64     int              j_coord_offsetA,j_coord_offsetB,j_coord_offsetC,j_coord_offsetD;
65     int              j_coord_offsetE,j_coord_offsetF,j_coord_offsetG,j_coord_offsetH;
66     int              *iinr,*jindex,*jjnr,*shiftidx,*gid;
67     real             rcutoff_scalar;
68     real             *shiftvec,*fshift,*x,*f;
69     real             *fjptrA,*fjptrB,*fjptrC,*fjptrD,*fjptrE,*fjptrF,*fjptrG,*fjptrH;
70     real             scratch[4*DIM];
71     __m256           tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
72     real *           vdwioffsetptr0;
73     __m256           ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
74     real *           vdwioffsetptr1;
75     __m256           ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
76     real *           vdwioffsetptr2;
77     __m256           ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
78     real *           vdwioffsetptr3;
79     __m256           ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
80     int              vdwjidx0A,vdwjidx0B,vdwjidx0C,vdwjidx0D,vdwjidx0E,vdwjidx0F,vdwjidx0G,vdwjidx0H;
81     __m256           jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
82     int              vdwjidx1A,vdwjidx1B,vdwjidx1C,vdwjidx1D,vdwjidx1E,vdwjidx1F,vdwjidx1G,vdwjidx1H;
83     __m256           jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
84     int              vdwjidx2A,vdwjidx2B,vdwjidx2C,vdwjidx2D,vdwjidx2E,vdwjidx2F,vdwjidx2G,vdwjidx2H;
85     __m256           jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
86     int              vdwjidx3A,vdwjidx3B,vdwjidx3C,vdwjidx3D,vdwjidx3E,vdwjidx3F,vdwjidx3G,vdwjidx3H;
87     __m256           jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
88     __m256           dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
89     __m256           dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
90     __m256           dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
91     __m256           dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
92     __m256           dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
93     __m256           dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
94     __m256           dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
95     __m256           dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
96     __m256           dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
97     __m256           dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
98     __m256           velec,felec,velecsum,facel,crf,krf,krf2;
99     real             *charge;
100     int              nvdwtype;
101     __m256           rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
102     int              *vdwtype;
103     real             *vdwparam;
104     __m256           one_sixth   = _mm256_set1_ps(1.0/6.0);
105     __m256           one_twelfth = _mm256_set1_ps(1.0/12.0);
106     __m256i          vfitab;
107     __m128i          vfitab_lo,vfitab_hi;
108     __m128i          ifour       = _mm_set1_epi32(4);
109     __m256           rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
110     real             *vftab;
111     __m256i          ewitab;
112     __m128i          ewitab_lo,ewitab_hi;
113     __m256           ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
114     __m256           beta,beta2,beta3,zeta2,pmecorrF,pmecorrV,rinv3;
115     real             *ewtab;
116     __m256           dummy_mask,cutoff_mask;
117     __m256           signbit = _mm256_castsi256_ps( _mm256_set1_epi32(0x80000000) );
118     __m256           one     = _mm256_set1_ps(1.0);
119     __m256           two     = _mm256_set1_ps(2.0);
120     x                = xx[0];
121     f                = ff[0];
122
123     nri              = nlist->nri;
124     iinr             = nlist->iinr;
125     jindex           = nlist->jindex;
126     jjnr             = nlist->jjnr;
127     shiftidx         = nlist->shift;
128     gid              = nlist->gid;
129     shiftvec         = fr->shift_vec[0];
130     fshift           = fr->fshift[0];
131     facel            = _mm256_set1_ps(fr->epsfac);
132     charge           = mdatoms->chargeA;
133     nvdwtype         = fr->ntype;
134     vdwparam         = fr->nbfp;
135     vdwtype          = mdatoms->typeA;
136
137     vftab            = kernel_data->table_vdw->data;
138     vftabscale       = _mm256_set1_ps(kernel_data->table_vdw->scale);
139
140     sh_ewald         = _mm256_set1_ps(fr->ic->sh_ewald);
141     beta             = _mm256_set1_ps(fr->ic->ewaldcoeff);
142     beta2            = _mm256_mul_ps(beta,beta);
143     beta3            = _mm256_mul_ps(beta,beta2);
144
145     ewtab            = fr->ic->tabq_coul_FDV0;
146     ewtabscale       = _mm256_set1_ps(fr->ic->tabq_scale);
147     ewtabhalfspace   = _mm256_set1_ps(0.5/fr->ic->tabq_scale);
148
149     /* Setup water-specific parameters */
150     inr              = nlist->iinr[0];
151     iq1              = _mm256_mul_ps(facel,_mm256_set1_ps(charge[inr+1]));
152     iq2              = _mm256_mul_ps(facel,_mm256_set1_ps(charge[inr+2]));
153     iq3              = _mm256_mul_ps(facel,_mm256_set1_ps(charge[inr+3]));
154     vdwioffsetptr0   = vdwparam+2*nvdwtype*vdwtype[inr+0];
155
156     jq1              = _mm256_set1_ps(charge[inr+1]);
157     jq2              = _mm256_set1_ps(charge[inr+2]);
158     jq3              = _mm256_set1_ps(charge[inr+3]);
159     vdwjidx0A        = 2*vdwtype[inr+0];
160     c6_00            = _mm256_set1_ps(vdwioffsetptr0[vdwjidx0A]);
161     c12_00           = _mm256_set1_ps(vdwioffsetptr0[vdwjidx0A+1]);
162     qq11             = _mm256_mul_ps(iq1,jq1);
163     qq12             = _mm256_mul_ps(iq1,jq2);
164     qq13             = _mm256_mul_ps(iq1,jq3);
165     qq21             = _mm256_mul_ps(iq2,jq1);
166     qq22             = _mm256_mul_ps(iq2,jq2);
167     qq23             = _mm256_mul_ps(iq2,jq3);
168     qq31             = _mm256_mul_ps(iq3,jq1);
169     qq32             = _mm256_mul_ps(iq3,jq2);
170     qq33             = _mm256_mul_ps(iq3,jq3);
171
172     /* Avoid stupid compiler warnings */
173     jnrA = jnrB = jnrC = jnrD = jnrE = jnrF = jnrG = jnrH = 0;
174     j_coord_offsetA = 0;
175     j_coord_offsetB = 0;
176     j_coord_offsetC = 0;
177     j_coord_offsetD = 0;
178     j_coord_offsetE = 0;
179     j_coord_offsetF = 0;
180     j_coord_offsetG = 0;
181     j_coord_offsetH = 0;
182
183     outeriter        = 0;
184     inneriter        = 0;
185
186     for(iidx=0;iidx<4*DIM;iidx++)
187     {
188         scratch[iidx] = 0.0;
189     }
190
191     /* Start outer loop over neighborlists */
192     for(iidx=0; iidx<nri; iidx++)
193     {
194         /* Load shift vector for this list */
195         i_shift_offset   = DIM*shiftidx[iidx];
196
197         /* Load limits for loop over neighbors */
198         j_index_start    = jindex[iidx];
199         j_index_end      = jindex[iidx+1];
200
201         /* Get outer coordinate index */
202         inr              = iinr[iidx];
203         i_coord_offset   = DIM*inr;
204
205         /* Load i particle coords and add shift vector */
206         gmx_mm256_load_shift_and_4rvec_broadcast_ps(shiftvec+i_shift_offset,x+i_coord_offset,
207                                                     &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
208
209         fix0             = _mm256_setzero_ps();
210         fiy0             = _mm256_setzero_ps();
211         fiz0             = _mm256_setzero_ps();
212         fix1             = _mm256_setzero_ps();
213         fiy1             = _mm256_setzero_ps();
214         fiz1             = _mm256_setzero_ps();
215         fix2             = _mm256_setzero_ps();
216         fiy2             = _mm256_setzero_ps();
217         fiz2             = _mm256_setzero_ps();
218         fix3             = _mm256_setzero_ps();
219         fiy3             = _mm256_setzero_ps();
220         fiz3             = _mm256_setzero_ps();
221
222         /* Reset potential sums */
223         velecsum         = _mm256_setzero_ps();
224         vvdwsum          = _mm256_setzero_ps();
225
226         /* Start inner kernel loop */
227         for(jidx=j_index_start; jidx<j_index_end && jjnr[jidx+7]>=0; jidx+=8)
228         {
229
230             /* Get j neighbor index, and coordinate index */
231             jnrA             = jjnr[jidx];
232             jnrB             = jjnr[jidx+1];
233             jnrC             = jjnr[jidx+2];
234             jnrD             = jjnr[jidx+3];
235             jnrE             = jjnr[jidx+4];
236             jnrF             = jjnr[jidx+5];
237             jnrG             = jjnr[jidx+6];
238             jnrH             = jjnr[jidx+7];
239             j_coord_offsetA  = DIM*jnrA;
240             j_coord_offsetB  = DIM*jnrB;
241             j_coord_offsetC  = DIM*jnrC;
242             j_coord_offsetD  = DIM*jnrD;
243             j_coord_offsetE  = DIM*jnrE;
244             j_coord_offsetF  = DIM*jnrF;
245             j_coord_offsetG  = DIM*jnrG;
246             j_coord_offsetH  = DIM*jnrH;
247
248             /* load j atom coordinates */
249             gmx_mm256_load_4rvec_8ptr_swizzle_ps(x+j_coord_offsetA,x+j_coord_offsetB,
250                                                  x+j_coord_offsetC,x+j_coord_offsetD,
251                                                  x+j_coord_offsetE,x+j_coord_offsetF,
252                                                  x+j_coord_offsetG,x+j_coord_offsetH,
253                                                  &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
254                                                  &jy2,&jz2,&jx3,&jy3,&jz3);
255
256             /* Calculate displacement vector */
257             dx00             = _mm256_sub_ps(ix0,jx0);
258             dy00             = _mm256_sub_ps(iy0,jy0);
259             dz00             = _mm256_sub_ps(iz0,jz0);
260             dx11             = _mm256_sub_ps(ix1,jx1);
261             dy11             = _mm256_sub_ps(iy1,jy1);
262             dz11             = _mm256_sub_ps(iz1,jz1);
263             dx12             = _mm256_sub_ps(ix1,jx2);
264             dy12             = _mm256_sub_ps(iy1,jy2);
265             dz12             = _mm256_sub_ps(iz1,jz2);
266             dx13             = _mm256_sub_ps(ix1,jx3);
267             dy13             = _mm256_sub_ps(iy1,jy3);
268             dz13             = _mm256_sub_ps(iz1,jz3);
269             dx21             = _mm256_sub_ps(ix2,jx1);
270             dy21             = _mm256_sub_ps(iy2,jy1);
271             dz21             = _mm256_sub_ps(iz2,jz1);
272             dx22             = _mm256_sub_ps(ix2,jx2);
273             dy22             = _mm256_sub_ps(iy2,jy2);
274             dz22             = _mm256_sub_ps(iz2,jz2);
275             dx23             = _mm256_sub_ps(ix2,jx3);
276             dy23             = _mm256_sub_ps(iy2,jy3);
277             dz23             = _mm256_sub_ps(iz2,jz3);
278             dx31             = _mm256_sub_ps(ix3,jx1);
279             dy31             = _mm256_sub_ps(iy3,jy1);
280             dz31             = _mm256_sub_ps(iz3,jz1);
281             dx32             = _mm256_sub_ps(ix3,jx2);
282             dy32             = _mm256_sub_ps(iy3,jy2);
283             dz32             = _mm256_sub_ps(iz3,jz2);
284             dx33             = _mm256_sub_ps(ix3,jx3);
285             dy33             = _mm256_sub_ps(iy3,jy3);
286             dz33             = _mm256_sub_ps(iz3,jz3);
287
288             /* Calculate squared distance and things based on it */
289             rsq00            = gmx_mm256_calc_rsq_ps(dx00,dy00,dz00);
290             rsq11            = gmx_mm256_calc_rsq_ps(dx11,dy11,dz11);
291             rsq12            = gmx_mm256_calc_rsq_ps(dx12,dy12,dz12);
292             rsq13            = gmx_mm256_calc_rsq_ps(dx13,dy13,dz13);
293             rsq21            = gmx_mm256_calc_rsq_ps(dx21,dy21,dz21);
294             rsq22            = gmx_mm256_calc_rsq_ps(dx22,dy22,dz22);
295             rsq23            = gmx_mm256_calc_rsq_ps(dx23,dy23,dz23);
296             rsq31            = gmx_mm256_calc_rsq_ps(dx31,dy31,dz31);
297             rsq32            = gmx_mm256_calc_rsq_ps(dx32,dy32,dz32);
298             rsq33            = gmx_mm256_calc_rsq_ps(dx33,dy33,dz33);
299
300             rinv00           = gmx_mm256_invsqrt_ps(rsq00);
301             rinv11           = gmx_mm256_invsqrt_ps(rsq11);
302             rinv12           = gmx_mm256_invsqrt_ps(rsq12);
303             rinv13           = gmx_mm256_invsqrt_ps(rsq13);
304             rinv21           = gmx_mm256_invsqrt_ps(rsq21);
305             rinv22           = gmx_mm256_invsqrt_ps(rsq22);
306             rinv23           = gmx_mm256_invsqrt_ps(rsq23);
307             rinv31           = gmx_mm256_invsqrt_ps(rsq31);
308             rinv32           = gmx_mm256_invsqrt_ps(rsq32);
309             rinv33           = gmx_mm256_invsqrt_ps(rsq33);
310
311             rinvsq11         = _mm256_mul_ps(rinv11,rinv11);
312             rinvsq12         = _mm256_mul_ps(rinv12,rinv12);
313             rinvsq13         = _mm256_mul_ps(rinv13,rinv13);
314             rinvsq21         = _mm256_mul_ps(rinv21,rinv21);
315             rinvsq22         = _mm256_mul_ps(rinv22,rinv22);
316             rinvsq23         = _mm256_mul_ps(rinv23,rinv23);
317             rinvsq31         = _mm256_mul_ps(rinv31,rinv31);
318             rinvsq32         = _mm256_mul_ps(rinv32,rinv32);
319             rinvsq33         = _mm256_mul_ps(rinv33,rinv33);
320
321             fjx0             = _mm256_setzero_ps();
322             fjy0             = _mm256_setzero_ps();
323             fjz0             = _mm256_setzero_ps();
324             fjx1             = _mm256_setzero_ps();
325             fjy1             = _mm256_setzero_ps();
326             fjz1             = _mm256_setzero_ps();
327             fjx2             = _mm256_setzero_ps();
328             fjy2             = _mm256_setzero_ps();
329             fjz2             = _mm256_setzero_ps();
330             fjx3             = _mm256_setzero_ps();
331             fjy3             = _mm256_setzero_ps();
332             fjz3             = _mm256_setzero_ps();
333
334             /**************************
335              * CALCULATE INTERACTIONS *
336              **************************/
337
338             r00              = _mm256_mul_ps(rsq00,rinv00);
339
340             /* Calculate table index by multiplying r with table scale and truncate to integer */
341             rt               = _mm256_mul_ps(r00,vftabscale);
342             vfitab           = _mm256_cvttps_epi32(rt);
343             vfeps            = _mm256_sub_ps(rt,_mm256_round_ps(rt, _MM_FROUND_FLOOR));
344             /*         AVX1 does not support 256-bit integer operations, so now we go to 128-bit mode... */
345             vfitab_lo        = _mm256_extractf128_si256(vfitab,0x0);
346             vfitab_hi        = _mm256_extractf128_si256(vfitab,0x1);
347             vfitab_lo        = _mm_slli_epi32(vfitab_lo,3);
348             vfitab_hi        = _mm_slli_epi32(vfitab_hi,3);
349
350             /* CUBIC SPLINE TABLE DISPERSION */
351             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
352                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
353             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
354                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
355             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
356                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
357             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
358                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
359             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
360             Heps             = _mm256_mul_ps(vfeps,H);
361             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
362             VV               = _mm256_add_ps(Y,_mm256_mul_ps(vfeps,Fp));
363             vvdw6            = _mm256_mul_ps(c6_00,VV);
364             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
365             fvdw6            = _mm256_mul_ps(c6_00,FF);
366
367             /* CUBIC SPLINE TABLE REPULSION */
368             vfitab_lo        = _mm_add_epi32(vfitab_lo,ifour);
369             vfitab_hi        = _mm_add_epi32(vfitab_hi,ifour);
370             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
371                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
372             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
373                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
374             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
375                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
376             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
377                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
378             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
379             Heps             = _mm256_mul_ps(vfeps,H);
380             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
381             VV               = _mm256_add_ps(Y,_mm256_mul_ps(vfeps,Fp));
382             vvdw12           = _mm256_mul_ps(c12_00,VV);
383             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
384             fvdw12           = _mm256_mul_ps(c12_00,FF);
385             vvdw             = _mm256_add_ps(vvdw12,vvdw6);
386             fvdw             = _mm256_xor_ps(signbit,_mm256_mul_ps(_mm256_add_ps(fvdw6,fvdw12),_mm256_mul_ps(vftabscale,rinv00)));
387
388             /* Update potential sum for this i atom from the interaction with this j atom. */
389             vvdwsum          = _mm256_add_ps(vvdwsum,vvdw);
390
391             fscal            = fvdw;
392
393             /* Calculate temporary vectorial force */
394             tx               = _mm256_mul_ps(fscal,dx00);
395             ty               = _mm256_mul_ps(fscal,dy00);
396             tz               = _mm256_mul_ps(fscal,dz00);
397
398             /* Update vectorial force */
399             fix0             = _mm256_add_ps(fix0,tx);
400             fiy0             = _mm256_add_ps(fiy0,ty);
401             fiz0             = _mm256_add_ps(fiz0,tz);
402
403             fjx0             = _mm256_add_ps(fjx0,tx);
404             fjy0             = _mm256_add_ps(fjy0,ty);
405             fjz0             = _mm256_add_ps(fjz0,tz);
406
407             /**************************
408              * CALCULATE INTERACTIONS *
409              **************************/
410
411             r11              = _mm256_mul_ps(rsq11,rinv11);
412
413             /* EWALD ELECTROSTATICS */
414             
415             /* Analytical PME correction */
416             zeta2            = _mm256_mul_ps(beta2,rsq11);
417             rinv3            = _mm256_mul_ps(rinvsq11,rinv11);
418             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
419             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
420             felec            = _mm256_mul_ps(qq11,felec);
421             pmecorrV         = gmx_mm256_pmecorrV_ps(zeta2);
422             pmecorrV         = _mm256_mul_ps(pmecorrV,beta);
423             velec            = _mm256_sub_ps(rinv11,pmecorrV);
424             velec            = _mm256_mul_ps(qq11,velec);
425             
426             /* Update potential sum for this i atom from the interaction with this j atom. */
427             velecsum         = _mm256_add_ps(velecsum,velec);
428
429             fscal            = felec;
430
431             /* Calculate temporary vectorial force */
432             tx               = _mm256_mul_ps(fscal,dx11);
433             ty               = _mm256_mul_ps(fscal,dy11);
434             tz               = _mm256_mul_ps(fscal,dz11);
435
436             /* Update vectorial force */
437             fix1             = _mm256_add_ps(fix1,tx);
438             fiy1             = _mm256_add_ps(fiy1,ty);
439             fiz1             = _mm256_add_ps(fiz1,tz);
440
441             fjx1             = _mm256_add_ps(fjx1,tx);
442             fjy1             = _mm256_add_ps(fjy1,ty);
443             fjz1             = _mm256_add_ps(fjz1,tz);
444
445             /**************************
446              * CALCULATE INTERACTIONS *
447              **************************/
448
449             r12              = _mm256_mul_ps(rsq12,rinv12);
450
451             /* EWALD ELECTROSTATICS */
452             
453             /* Analytical PME correction */
454             zeta2            = _mm256_mul_ps(beta2,rsq12);
455             rinv3            = _mm256_mul_ps(rinvsq12,rinv12);
456             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
457             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
458             felec            = _mm256_mul_ps(qq12,felec);
459             pmecorrV         = gmx_mm256_pmecorrV_ps(zeta2);
460             pmecorrV         = _mm256_mul_ps(pmecorrV,beta);
461             velec            = _mm256_sub_ps(rinv12,pmecorrV);
462             velec            = _mm256_mul_ps(qq12,velec);
463             
464             /* Update potential sum for this i atom from the interaction with this j atom. */
465             velecsum         = _mm256_add_ps(velecsum,velec);
466
467             fscal            = felec;
468
469             /* Calculate temporary vectorial force */
470             tx               = _mm256_mul_ps(fscal,dx12);
471             ty               = _mm256_mul_ps(fscal,dy12);
472             tz               = _mm256_mul_ps(fscal,dz12);
473
474             /* Update vectorial force */
475             fix1             = _mm256_add_ps(fix1,tx);
476             fiy1             = _mm256_add_ps(fiy1,ty);
477             fiz1             = _mm256_add_ps(fiz1,tz);
478
479             fjx2             = _mm256_add_ps(fjx2,tx);
480             fjy2             = _mm256_add_ps(fjy2,ty);
481             fjz2             = _mm256_add_ps(fjz2,tz);
482
483             /**************************
484              * CALCULATE INTERACTIONS *
485              **************************/
486
487             r13              = _mm256_mul_ps(rsq13,rinv13);
488
489             /* EWALD ELECTROSTATICS */
490             
491             /* Analytical PME correction */
492             zeta2            = _mm256_mul_ps(beta2,rsq13);
493             rinv3            = _mm256_mul_ps(rinvsq13,rinv13);
494             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
495             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
496             felec            = _mm256_mul_ps(qq13,felec);
497             pmecorrV         = gmx_mm256_pmecorrV_ps(zeta2);
498             pmecorrV         = _mm256_mul_ps(pmecorrV,beta);
499             velec            = _mm256_sub_ps(rinv13,pmecorrV);
500             velec            = _mm256_mul_ps(qq13,velec);
501             
502             /* Update potential sum for this i atom from the interaction with this j atom. */
503             velecsum         = _mm256_add_ps(velecsum,velec);
504
505             fscal            = felec;
506
507             /* Calculate temporary vectorial force */
508             tx               = _mm256_mul_ps(fscal,dx13);
509             ty               = _mm256_mul_ps(fscal,dy13);
510             tz               = _mm256_mul_ps(fscal,dz13);
511
512             /* Update vectorial force */
513             fix1             = _mm256_add_ps(fix1,tx);
514             fiy1             = _mm256_add_ps(fiy1,ty);
515             fiz1             = _mm256_add_ps(fiz1,tz);
516
517             fjx3             = _mm256_add_ps(fjx3,tx);
518             fjy3             = _mm256_add_ps(fjy3,ty);
519             fjz3             = _mm256_add_ps(fjz3,tz);
520
521             /**************************
522              * CALCULATE INTERACTIONS *
523              **************************/
524
525             r21              = _mm256_mul_ps(rsq21,rinv21);
526
527             /* EWALD ELECTROSTATICS */
528             
529             /* Analytical PME correction */
530             zeta2            = _mm256_mul_ps(beta2,rsq21);
531             rinv3            = _mm256_mul_ps(rinvsq21,rinv21);
532             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
533             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
534             felec            = _mm256_mul_ps(qq21,felec);
535             pmecorrV         = gmx_mm256_pmecorrV_ps(zeta2);
536             pmecorrV         = _mm256_mul_ps(pmecorrV,beta);
537             velec            = _mm256_sub_ps(rinv21,pmecorrV);
538             velec            = _mm256_mul_ps(qq21,velec);
539             
540             /* Update potential sum for this i atom from the interaction with this j atom. */
541             velecsum         = _mm256_add_ps(velecsum,velec);
542
543             fscal            = felec;
544
545             /* Calculate temporary vectorial force */
546             tx               = _mm256_mul_ps(fscal,dx21);
547             ty               = _mm256_mul_ps(fscal,dy21);
548             tz               = _mm256_mul_ps(fscal,dz21);
549
550             /* Update vectorial force */
551             fix2             = _mm256_add_ps(fix2,tx);
552             fiy2             = _mm256_add_ps(fiy2,ty);
553             fiz2             = _mm256_add_ps(fiz2,tz);
554
555             fjx1             = _mm256_add_ps(fjx1,tx);
556             fjy1             = _mm256_add_ps(fjy1,ty);
557             fjz1             = _mm256_add_ps(fjz1,tz);
558
559             /**************************
560              * CALCULATE INTERACTIONS *
561              **************************/
562
563             r22              = _mm256_mul_ps(rsq22,rinv22);
564
565             /* EWALD ELECTROSTATICS */
566             
567             /* Analytical PME correction */
568             zeta2            = _mm256_mul_ps(beta2,rsq22);
569             rinv3            = _mm256_mul_ps(rinvsq22,rinv22);
570             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
571             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
572             felec            = _mm256_mul_ps(qq22,felec);
573             pmecorrV         = gmx_mm256_pmecorrV_ps(zeta2);
574             pmecorrV         = _mm256_mul_ps(pmecorrV,beta);
575             velec            = _mm256_sub_ps(rinv22,pmecorrV);
576             velec            = _mm256_mul_ps(qq22,velec);
577             
578             /* Update potential sum for this i atom from the interaction with this j atom. */
579             velecsum         = _mm256_add_ps(velecsum,velec);
580
581             fscal            = felec;
582
583             /* Calculate temporary vectorial force */
584             tx               = _mm256_mul_ps(fscal,dx22);
585             ty               = _mm256_mul_ps(fscal,dy22);
586             tz               = _mm256_mul_ps(fscal,dz22);
587
588             /* Update vectorial force */
589             fix2             = _mm256_add_ps(fix2,tx);
590             fiy2             = _mm256_add_ps(fiy2,ty);
591             fiz2             = _mm256_add_ps(fiz2,tz);
592
593             fjx2             = _mm256_add_ps(fjx2,tx);
594             fjy2             = _mm256_add_ps(fjy2,ty);
595             fjz2             = _mm256_add_ps(fjz2,tz);
596
597             /**************************
598              * CALCULATE INTERACTIONS *
599              **************************/
600
601             r23              = _mm256_mul_ps(rsq23,rinv23);
602
603             /* EWALD ELECTROSTATICS */
604             
605             /* Analytical PME correction */
606             zeta2            = _mm256_mul_ps(beta2,rsq23);
607             rinv3            = _mm256_mul_ps(rinvsq23,rinv23);
608             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
609             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
610             felec            = _mm256_mul_ps(qq23,felec);
611             pmecorrV         = gmx_mm256_pmecorrV_ps(zeta2);
612             pmecorrV         = _mm256_mul_ps(pmecorrV,beta);
613             velec            = _mm256_sub_ps(rinv23,pmecorrV);
614             velec            = _mm256_mul_ps(qq23,velec);
615             
616             /* Update potential sum for this i atom from the interaction with this j atom. */
617             velecsum         = _mm256_add_ps(velecsum,velec);
618
619             fscal            = felec;
620
621             /* Calculate temporary vectorial force */
622             tx               = _mm256_mul_ps(fscal,dx23);
623             ty               = _mm256_mul_ps(fscal,dy23);
624             tz               = _mm256_mul_ps(fscal,dz23);
625
626             /* Update vectorial force */
627             fix2             = _mm256_add_ps(fix2,tx);
628             fiy2             = _mm256_add_ps(fiy2,ty);
629             fiz2             = _mm256_add_ps(fiz2,tz);
630
631             fjx3             = _mm256_add_ps(fjx3,tx);
632             fjy3             = _mm256_add_ps(fjy3,ty);
633             fjz3             = _mm256_add_ps(fjz3,tz);
634
635             /**************************
636              * CALCULATE INTERACTIONS *
637              **************************/
638
639             r31              = _mm256_mul_ps(rsq31,rinv31);
640
641             /* EWALD ELECTROSTATICS */
642             
643             /* Analytical PME correction */
644             zeta2            = _mm256_mul_ps(beta2,rsq31);
645             rinv3            = _mm256_mul_ps(rinvsq31,rinv31);
646             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
647             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
648             felec            = _mm256_mul_ps(qq31,felec);
649             pmecorrV         = gmx_mm256_pmecorrV_ps(zeta2);
650             pmecorrV         = _mm256_mul_ps(pmecorrV,beta);
651             velec            = _mm256_sub_ps(rinv31,pmecorrV);
652             velec            = _mm256_mul_ps(qq31,velec);
653             
654             /* Update potential sum for this i atom from the interaction with this j atom. */
655             velecsum         = _mm256_add_ps(velecsum,velec);
656
657             fscal            = felec;
658
659             /* Calculate temporary vectorial force */
660             tx               = _mm256_mul_ps(fscal,dx31);
661             ty               = _mm256_mul_ps(fscal,dy31);
662             tz               = _mm256_mul_ps(fscal,dz31);
663
664             /* Update vectorial force */
665             fix3             = _mm256_add_ps(fix3,tx);
666             fiy3             = _mm256_add_ps(fiy3,ty);
667             fiz3             = _mm256_add_ps(fiz3,tz);
668
669             fjx1             = _mm256_add_ps(fjx1,tx);
670             fjy1             = _mm256_add_ps(fjy1,ty);
671             fjz1             = _mm256_add_ps(fjz1,tz);
672
673             /**************************
674              * CALCULATE INTERACTIONS *
675              **************************/
676
677             r32              = _mm256_mul_ps(rsq32,rinv32);
678
679             /* EWALD ELECTROSTATICS */
680             
681             /* Analytical PME correction */
682             zeta2            = _mm256_mul_ps(beta2,rsq32);
683             rinv3            = _mm256_mul_ps(rinvsq32,rinv32);
684             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
685             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
686             felec            = _mm256_mul_ps(qq32,felec);
687             pmecorrV         = gmx_mm256_pmecorrV_ps(zeta2);
688             pmecorrV         = _mm256_mul_ps(pmecorrV,beta);
689             velec            = _mm256_sub_ps(rinv32,pmecorrV);
690             velec            = _mm256_mul_ps(qq32,velec);
691             
692             /* Update potential sum for this i atom from the interaction with this j atom. */
693             velecsum         = _mm256_add_ps(velecsum,velec);
694
695             fscal            = felec;
696
697             /* Calculate temporary vectorial force */
698             tx               = _mm256_mul_ps(fscal,dx32);
699             ty               = _mm256_mul_ps(fscal,dy32);
700             tz               = _mm256_mul_ps(fscal,dz32);
701
702             /* Update vectorial force */
703             fix3             = _mm256_add_ps(fix3,tx);
704             fiy3             = _mm256_add_ps(fiy3,ty);
705             fiz3             = _mm256_add_ps(fiz3,tz);
706
707             fjx2             = _mm256_add_ps(fjx2,tx);
708             fjy2             = _mm256_add_ps(fjy2,ty);
709             fjz2             = _mm256_add_ps(fjz2,tz);
710
711             /**************************
712              * CALCULATE INTERACTIONS *
713              **************************/
714
715             r33              = _mm256_mul_ps(rsq33,rinv33);
716
717             /* EWALD ELECTROSTATICS */
718             
719             /* Analytical PME correction */
720             zeta2            = _mm256_mul_ps(beta2,rsq33);
721             rinv3            = _mm256_mul_ps(rinvsq33,rinv33);
722             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
723             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
724             felec            = _mm256_mul_ps(qq33,felec);
725             pmecorrV         = gmx_mm256_pmecorrV_ps(zeta2);
726             pmecorrV         = _mm256_mul_ps(pmecorrV,beta);
727             velec            = _mm256_sub_ps(rinv33,pmecorrV);
728             velec            = _mm256_mul_ps(qq33,velec);
729             
730             /* Update potential sum for this i atom from the interaction with this j atom. */
731             velecsum         = _mm256_add_ps(velecsum,velec);
732
733             fscal            = felec;
734
735             /* Calculate temporary vectorial force */
736             tx               = _mm256_mul_ps(fscal,dx33);
737             ty               = _mm256_mul_ps(fscal,dy33);
738             tz               = _mm256_mul_ps(fscal,dz33);
739
740             /* Update vectorial force */
741             fix3             = _mm256_add_ps(fix3,tx);
742             fiy3             = _mm256_add_ps(fiy3,ty);
743             fiz3             = _mm256_add_ps(fiz3,tz);
744
745             fjx3             = _mm256_add_ps(fjx3,tx);
746             fjy3             = _mm256_add_ps(fjy3,ty);
747             fjz3             = _mm256_add_ps(fjz3,tz);
748
749             fjptrA             = f+j_coord_offsetA;
750             fjptrB             = f+j_coord_offsetB;
751             fjptrC             = f+j_coord_offsetC;
752             fjptrD             = f+j_coord_offsetD;
753             fjptrE             = f+j_coord_offsetE;
754             fjptrF             = f+j_coord_offsetF;
755             fjptrG             = f+j_coord_offsetG;
756             fjptrH             = f+j_coord_offsetH;
757
758             gmx_mm256_decrement_4rvec_8ptr_swizzle_ps(fjptrA,fjptrB,fjptrC,fjptrD,fjptrE,fjptrF,fjptrG,fjptrH,
759                                                       fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,
760                                                       fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
761
762             /* Inner loop uses 815 flops */
763         }
764
765         if(jidx<j_index_end)
766         {
767
768             /* Get j neighbor index, and coordinate index */
769             jnrlistA         = jjnr[jidx];
770             jnrlistB         = jjnr[jidx+1];
771             jnrlistC         = jjnr[jidx+2];
772             jnrlistD         = jjnr[jidx+3];
773             jnrlistE         = jjnr[jidx+4];
774             jnrlistF         = jjnr[jidx+5];
775             jnrlistG         = jjnr[jidx+6];
776             jnrlistH         = jjnr[jidx+7];
777             /* Sign of each element will be negative for non-real atoms.
778              * This mask will be 0xFFFFFFFF for dummy entries and 0x0 for real ones,
779              * so use it as val = _mm_andnot_ps(mask,val) to clear dummy entries.
780              */
781             dummy_mask = gmx_mm256_set_m128(gmx_mm_castsi128_ps(_mm_cmplt_epi32(_mm_loadu_si128((const __m128i *)(jjnr+jidx+4)),_mm_setzero_si128())),
782                                             gmx_mm_castsi128_ps(_mm_cmplt_epi32(_mm_loadu_si128((const __m128i *)(jjnr+jidx)),_mm_setzero_si128())));
783                                             
784             jnrA       = (jnrlistA>=0) ? jnrlistA : 0;
785             jnrB       = (jnrlistB>=0) ? jnrlistB : 0;
786             jnrC       = (jnrlistC>=0) ? jnrlistC : 0;
787             jnrD       = (jnrlistD>=0) ? jnrlistD : 0;
788             jnrE       = (jnrlistE>=0) ? jnrlistE : 0;
789             jnrF       = (jnrlistF>=0) ? jnrlistF : 0;
790             jnrG       = (jnrlistG>=0) ? jnrlistG : 0;
791             jnrH       = (jnrlistH>=0) ? jnrlistH : 0;
792             j_coord_offsetA  = DIM*jnrA;
793             j_coord_offsetB  = DIM*jnrB;
794             j_coord_offsetC  = DIM*jnrC;
795             j_coord_offsetD  = DIM*jnrD;
796             j_coord_offsetE  = DIM*jnrE;
797             j_coord_offsetF  = DIM*jnrF;
798             j_coord_offsetG  = DIM*jnrG;
799             j_coord_offsetH  = DIM*jnrH;
800
801             /* load j atom coordinates */
802             gmx_mm256_load_4rvec_8ptr_swizzle_ps(x+j_coord_offsetA,x+j_coord_offsetB,
803                                                  x+j_coord_offsetC,x+j_coord_offsetD,
804                                                  x+j_coord_offsetE,x+j_coord_offsetF,
805                                                  x+j_coord_offsetG,x+j_coord_offsetH,
806                                                  &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
807                                                  &jy2,&jz2,&jx3,&jy3,&jz3);
808
809             /* Calculate displacement vector */
810             dx00             = _mm256_sub_ps(ix0,jx0);
811             dy00             = _mm256_sub_ps(iy0,jy0);
812             dz00             = _mm256_sub_ps(iz0,jz0);
813             dx11             = _mm256_sub_ps(ix1,jx1);
814             dy11             = _mm256_sub_ps(iy1,jy1);
815             dz11             = _mm256_sub_ps(iz1,jz1);
816             dx12             = _mm256_sub_ps(ix1,jx2);
817             dy12             = _mm256_sub_ps(iy1,jy2);
818             dz12             = _mm256_sub_ps(iz1,jz2);
819             dx13             = _mm256_sub_ps(ix1,jx3);
820             dy13             = _mm256_sub_ps(iy1,jy3);
821             dz13             = _mm256_sub_ps(iz1,jz3);
822             dx21             = _mm256_sub_ps(ix2,jx1);
823             dy21             = _mm256_sub_ps(iy2,jy1);
824             dz21             = _mm256_sub_ps(iz2,jz1);
825             dx22             = _mm256_sub_ps(ix2,jx2);
826             dy22             = _mm256_sub_ps(iy2,jy2);
827             dz22             = _mm256_sub_ps(iz2,jz2);
828             dx23             = _mm256_sub_ps(ix2,jx3);
829             dy23             = _mm256_sub_ps(iy2,jy3);
830             dz23             = _mm256_sub_ps(iz2,jz3);
831             dx31             = _mm256_sub_ps(ix3,jx1);
832             dy31             = _mm256_sub_ps(iy3,jy1);
833             dz31             = _mm256_sub_ps(iz3,jz1);
834             dx32             = _mm256_sub_ps(ix3,jx2);
835             dy32             = _mm256_sub_ps(iy3,jy2);
836             dz32             = _mm256_sub_ps(iz3,jz2);
837             dx33             = _mm256_sub_ps(ix3,jx3);
838             dy33             = _mm256_sub_ps(iy3,jy3);
839             dz33             = _mm256_sub_ps(iz3,jz3);
840
841             /* Calculate squared distance and things based on it */
842             rsq00            = gmx_mm256_calc_rsq_ps(dx00,dy00,dz00);
843             rsq11            = gmx_mm256_calc_rsq_ps(dx11,dy11,dz11);
844             rsq12            = gmx_mm256_calc_rsq_ps(dx12,dy12,dz12);
845             rsq13            = gmx_mm256_calc_rsq_ps(dx13,dy13,dz13);
846             rsq21            = gmx_mm256_calc_rsq_ps(dx21,dy21,dz21);
847             rsq22            = gmx_mm256_calc_rsq_ps(dx22,dy22,dz22);
848             rsq23            = gmx_mm256_calc_rsq_ps(dx23,dy23,dz23);
849             rsq31            = gmx_mm256_calc_rsq_ps(dx31,dy31,dz31);
850             rsq32            = gmx_mm256_calc_rsq_ps(dx32,dy32,dz32);
851             rsq33            = gmx_mm256_calc_rsq_ps(dx33,dy33,dz33);
852
853             rinv00           = gmx_mm256_invsqrt_ps(rsq00);
854             rinv11           = gmx_mm256_invsqrt_ps(rsq11);
855             rinv12           = gmx_mm256_invsqrt_ps(rsq12);
856             rinv13           = gmx_mm256_invsqrt_ps(rsq13);
857             rinv21           = gmx_mm256_invsqrt_ps(rsq21);
858             rinv22           = gmx_mm256_invsqrt_ps(rsq22);
859             rinv23           = gmx_mm256_invsqrt_ps(rsq23);
860             rinv31           = gmx_mm256_invsqrt_ps(rsq31);
861             rinv32           = gmx_mm256_invsqrt_ps(rsq32);
862             rinv33           = gmx_mm256_invsqrt_ps(rsq33);
863
864             rinvsq11         = _mm256_mul_ps(rinv11,rinv11);
865             rinvsq12         = _mm256_mul_ps(rinv12,rinv12);
866             rinvsq13         = _mm256_mul_ps(rinv13,rinv13);
867             rinvsq21         = _mm256_mul_ps(rinv21,rinv21);
868             rinvsq22         = _mm256_mul_ps(rinv22,rinv22);
869             rinvsq23         = _mm256_mul_ps(rinv23,rinv23);
870             rinvsq31         = _mm256_mul_ps(rinv31,rinv31);
871             rinvsq32         = _mm256_mul_ps(rinv32,rinv32);
872             rinvsq33         = _mm256_mul_ps(rinv33,rinv33);
873
874             fjx0             = _mm256_setzero_ps();
875             fjy0             = _mm256_setzero_ps();
876             fjz0             = _mm256_setzero_ps();
877             fjx1             = _mm256_setzero_ps();
878             fjy1             = _mm256_setzero_ps();
879             fjz1             = _mm256_setzero_ps();
880             fjx2             = _mm256_setzero_ps();
881             fjy2             = _mm256_setzero_ps();
882             fjz2             = _mm256_setzero_ps();
883             fjx3             = _mm256_setzero_ps();
884             fjy3             = _mm256_setzero_ps();
885             fjz3             = _mm256_setzero_ps();
886
887             /**************************
888              * CALCULATE INTERACTIONS *
889              **************************/
890
891             r00              = _mm256_mul_ps(rsq00,rinv00);
892             r00              = _mm256_andnot_ps(dummy_mask,r00);
893
894             /* Calculate table index by multiplying r with table scale and truncate to integer */
895             rt               = _mm256_mul_ps(r00,vftabscale);
896             vfitab           = _mm256_cvttps_epi32(rt);
897             vfeps            = _mm256_sub_ps(rt,_mm256_round_ps(rt, _MM_FROUND_FLOOR));
898             /*         AVX1 does not support 256-bit integer operations, so now we go to 128-bit mode... */
899             vfitab_lo        = _mm256_extractf128_si256(vfitab,0x0);
900             vfitab_hi        = _mm256_extractf128_si256(vfitab,0x1);
901             vfitab_lo        = _mm_slli_epi32(vfitab_lo,3);
902             vfitab_hi        = _mm_slli_epi32(vfitab_hi,3);
903
904             /* CUBIC SPLINE TABLE DISPERSION */
905             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
906                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
907             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
908                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
909             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
910                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
911             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
912                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
913             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
914             Heps             = _mm256_mul_ps(vfeps,H);
915             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
916             VV               = _mm256_add_ps(Y,_mm256_mul_ps(vfeps,Fp));
917             vvdw6            = _mm256_mul_ps(c6_00,VV);
918             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
919             fvdw6            = _mm256_mul_ps(c6_00,FF);
920
921             /* CUBIC SPLINE TABLE REPULSION */
922             vfitab_lo        = _mm_add_epi32(vfitab_lo,ifour);
923             vfitab_hi        = _mm_add_epi32(vfitab_hi,ifour);
924             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
925                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
926             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
927                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
928             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
929                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
930             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
931                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
932             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
933             Heps             = _mm256_mul_ps(vfeps,H);
934             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
935             VV               = _mm256_add_ps(Y,_mm256_mul_ps(vfeps,Fp));
936             vvdw12           = _mm256_mul_ps(c12_00,VV);
937             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
938             fvdw12           = _mm256_mul_ps(c12_00,FF);
939             vvdw             = _mm256_add_ps(vvdw12,vvdw6);
940             fvdw             = _mm256_xor_ps(signbit,_mm256_mul_ps(_mm256_add_ps(fvdw6,fvdw12),_mm256_mul_ps(vftabscale,rinv00)));
941
942             /* Update potential sum for this i atom from the interaction with this j atom. */
943             vvdw             = _mm256_andnot_ps(dummy_mask,vvdw);
944             vvdwsum          = _mm256_add_ps(vvdwsum,vvdw);
945
946             fscal            = fvdw;
947
948             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
949
950             /* Calculate temporary vectorial force */
951             tx               = _mm256_mul_ps(fscal,dx00);
952             ty               = _mm256_mul_ps(fscal,dy00);
953             tz               = _mm256_mul_ps(fscal,dz00);
954
955             /* Update vectorial force */
956             fix0             = _mm256_add_ps(fix0,tx);
957             fiy0             = _mm256_add_ps(fiy0,ty);
958             fiz0             = _mm256_add_ps(fiz0,tz);
959
960             fjx0             = _mm256_add_ps(fjx0,tx);
961             fjy0             = _mm256_add_ps(fjy0,ty);
962             fjz0             = _mm256_add_ps(fjz0,tz);
963
964             /**************************
965              * CALCULATE INTERACTIONS *
966              **************************/
967
968             r11              = _mm256_mul_ps(rsq11,rinv11);
969             r11              = _mm256_andnot_ps(dummy_mask,r11);
970
971             /* EWALD ELECTROSTATICS */
972             
973             /* Analytical PME correction */
974             zeta2            = _mm256_mul_ps(beta2,rsq11);
975             rinv3            = _mm256_mul_ps(rinvsq11,rinv11);
976             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
977             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
978             felec            = _mm256_mul_ps(qq11,felec);
979             pmecorrV         = gmx_mm256_pmecorrV_ps(zeta2);
980             pmecorrV         = _mm256_mul_ps(pmecorrV,beta);
981             velec            = _mm256_sub_ps(rinv11,pmecorrV);
982             velec            = _mm256_mul_ps(qq11,velec);
983             
984             /* Update potential sum for this i atom from the interaction with this j atom. */
985             velec            = _mm256_andnot_ps(dummy_mask,velec);
986             velecsum         = _mm256_add_ps(velecsum,velec);
987
988             fscal            = felec;
989
990             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
991
992             /* Calculate temporary vectorial force */
993             tx               = _mm256_mul_ps(fscal,dx11);
994             ty               = _mm256_mul_ps(fscal,dy11);
995             tz               = _mm256_mul_ps(fscal,dz11);
996
997             /* Update vectorial force */
998             fix1             = _mm256_add_ps(fix1,tx);
999             fiy1             = _mm256_add_ps(fiy1,ty);
1000             fiz1             = _mm256_add_ps(fiz1,tz);
1001
1002             fjx1             = _mm256_add_ps(fjx1,tx);
1003             fjy1             = _mm256_add_ps(fjy1,ty);
1004             fjz1             = _mm256_add_ps(fjz1,tz);
1005
1006             /**************************
1007              * CALCULATE INTERACTIONS *
1008              **************************/
1009
1010             r12              = _mm256_mul_ps(rsq12,rinv12);
1011             r12              = _mm256_andnot_ps(dummy_mask,r12);
1012
1013             /* EWALD ELECTROSTATICS */
1014             
1015             /* Analytical PME correction */
1016             zeta2            = _mm256_mul_ps(beta2,rsq12);
1017             rinv3            = _mm256_mul_ps(rinvsq12,rinv12);
1018             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
1019             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
1020             felec            = _mm256_mul_ps(qq12,felec);
1021             pmecorrV         = gmx_mm256_pmecorrV_ps(zeta2);
1022             pmecorrV         = _mm256_mul_ps(pmecorrV,beta);
1023             velec            = _mm256_sub_ps(rinv12,pmecorrV);
1024             velec            = _mm256_mul_ps(qq12,velec);
1025             
1026             /* Update potential sum for this i atom from the interaction with this j atom. */
1027             velec            = _mm256_andnot_ps(dummy_mask,velec);
1028             velecsum         = _mm256_add_ps(velecsum,velec);
1029
1030             fscal            = felec;
1031
1032             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
1033
1034             /* Calculate temporary vectorial force */
1035             tx               = _mm256_mul_ps(fscal,dx12);
1036             ty               = _mm256_mul_ps(fscal,dy12);
1037             tz               = _mm256_mul_ps(fscal,dz12);
1038
1039             /* Update vectorial force */
1040             fix1             = _mm256_add_ps(fix1,tx);
1041             fiy1             = _mm256_add_ps(fiy1,ty);
1042             fiz1             = _mm256_add_ps(fiz1,tz);
1043
1044             fjx2             = _mm256_add_ps(fjx2,tx);
1045             fjy2             = _mm256_add_ps(fjy2,ty);
1046             fjz2             = _mm256_add_ps(fjz2,tz);
1047
1048             /**************************
1049              * CALCULATE INTERACTIONS *
1050              **************************/
1051
1052             r13              = _mm256_mul_ps(rsq13,rinv13);
1053             r13              = _mm256_andnot_ps(dummy_mask,r13);
1054
1055             /* EWALD ELECTROSTATICS */
1056             
1057             /* Analytical PME correction */
1058             zeta2            = _mm256_mul_ps(beta2,rsq13);
1059             rinv3            = _mm256_mul_ps(rinvsq13,rinv13);
1060             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
1061             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
1062             felec            = _mm256_mul_ps(qq13,felec);
1063             pmecorrV         = gmx_mm256_pmecorrV_ps(zeta2);
1064             pmecorrV         = _mm256_mul_ps(pmecorrV,beta);
1065             velec            = _mm256_sub_ps(rinv13,pmecorrV);
1066             velec            = _mm256_mul_ps(qq13,velec);
1067             
1068             /* Update potential sum for this i atom from the interaction with this j atom. */
1069             velec            = _mm256_andnot_ps(dummy_mask,velec);
1070             velecsum         = _mm256_add_ps(velecsum,velec);
1071
1072             fscal            = felec;
1073
1074             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
1075
1076             /* Calculate temporary vectorial force */
1077             tx               = _mm256_mul_ps(fscal,dx13);
1078             ty               = _mm256_mul_ps(fscal,dy13);
1079             tz               = _mm256_mul_ps(fscal,dz13);
1080
1081             /* Update vectorial force */
1082             fix1             = _mm256_add_ps(fix1,tx);
1083             fiy1             = _mm256_add_ps(fiy1,ty);
1084             fiz1             = _mm256_add_ps(fiz1,tz);
1085
1086             fjx3             = _mm256_add_ps(fjx3,tx);
1087             fjy3             = _mm256_add_ps(fjy3,ty);
1088             fjz3             = _mm256_add_ps(fjz3,tz);
1089
1090             /**************************
1091              * CALCULATE INTERACTIONS *
1092              **************************/
1093
1094             r21              = _mm256_mul_ps(rsq21,rinv21);
1095             r21              = _mm256_andnot_ps(dummy_mask,r21);
1096
1097             /* EWALD ELECTROSTATICS */
1098             
1099             /* Analytical PME correction */
1100             zeta2            = _mm256_mul_ps(beta2,rsq21);
1101             rinv3            = _mm256_mul_ps(rinvsq21,rinv21);
1102             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
1103             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
1104             felec            = _mm256_mul_ps(qq21,felec);
1105             pmecorrV         = gmx_mm256_pmecorrV_ps(zeta2);
1106             pmecorrV         = _mm256_mul_ps(pmecorrV,beta);
1107             velec            = _mm256_sub_ps(rinv21,pmecorrV);
1108             velec            = _mm256_mul_ps(qq21,velec);
1109             
1110             /* Update potential sum for this i atom from the interaction with this j atom. */
1111             velec            = _mm256_andnot_ps(dummy_mask,velec);
1112             velecsum         = _mm256_add_ps(velecsum,velec);
1113
1114             fscal            = felec;
1115
1116             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
1117
1118             /* Calculate temporary vectorial force */
1119             tx               = _mm256_mul_ps(fscal,dx21);
1120             ty               = _mm256_mul_ps(fscal,dy21);
1121             tz               = _mm256_mul_ps(fscal,dz21);
1122
1123             /* Update vectorial force */
1124             fix2             = _mm256_add_ps(fix2,tx);
1125             fiy2             = _mm256_add_ps(fiy2,ty);
1126             fiz2             = _mm256_add_ps(fiz2,tz);
1127
1128             fjx1             = _mm256_add_ps(fjx1,tx);
1129             fjy1             = _mm256_add_ps(fjy1,ty);
1130             fjz1             = _mm256_add_ps(fjz1,tz);
1131
1132             /**************************
1133              * CALCULATE INTERACTIONS *
1134              **************************/
1135
1136             r22              = _mm256_mul_ps(rsq22,rinv22);
1137             r22              = _mm256_andnot_ps(dummy_mask,r22);
1138
1139             /* EWALD ELECTROSTATICS */
1140             
1141             /* Analytical PME correction */
1142             zeta2            = _mm256_mul_ps(beta2,rsq22);
1143             rinv3            = _mm256_mul_ps(rinvsq22,rinv22);
1144             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
1145             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
1146             felec            = _mm256_mul_ps(qq22,felec);
1147             pmecorrV         = gmx_mm256_pmecorrV_ps(zeta2);
1148             pmecorrV         = _mm256_mul_ps(pmecorrV,beta);
1149             velec            = _mm256_sub_ps(rinv22,pmecorrV);
1150             velec            = _mm256_mul_ps(qq22,velec);
1151             
1152             /* Update potential sum for this i atom from the interaction with this j atom. */
1153             velec            = _mm256_andnot_ps(dummy_mask,velec);
1154             velecsum         = _mm256_add_ps(velecsum,velec);
1155
1156             fscal            = felec;
1157
1158             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
1159
1160             /* Calculate temporary vectorial force */
1161             tx               = _mm256_mul_ps(fscal,dx22);
1162             ty               = _mm256_mul_ps(fscal,dy22);
1163             tz               = _mm256_mul_ps(fscal,dz22);
1164
1165             /* Update vectorial force */
1166             fix2             = _mm256_add_ps(fix2,tx);
1167             fiy2             = _mm256_add_ps(fiy2,ty);
1168             fiz2             = _mm256_add_ps(fiz2,tz);
1169
1170             fjx2             = _mm256_add_ps(fjx2,tx);
1171             fjy2             = _mm256_add_ps(fjy2,ty);
1172             fjz2             = _mm256_add_ps(fjz2,tz);
1173
1174             /**************************
1175              * CALCULATE INTERACTIONS *
1176              **************************/
1177
1178             r23              = _mm256_mul_ps(rsq23,rinv23);
1179             r23              = _mm256_andnot_ps(dummy_mask,r23);
1180
1181             /* EWALD ELECTROSTATICS */
1182             
1183             /* Analytical PME correction */
1184             zeta2            = _mm256_mul_ps(beta2,rsq23);
1185             rinv3            = _mm256_mul_ps(rinvsq23,rinv23);
1186             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
1187             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
1188             felec            = _mm256_mul_ps(qq23,felec);
1189             pmecorrV         = gmx_mm256_pmecorrV_ps(zeta2);
1190             pmecorrV         = _mm256_mul_ps(pmecorrV,beta);
1191             velec            = _mm256_sub_ps(rinv23,pmecorrV);
1192             velec            = _mm256_mul_ps(qq23,velec);
1193             
1194             /* Update potential sum for this i atom from the interaction with this j atom. */
1195             velec            = _mm256_andnot_ps(dummy_mask,velec);
1196             velecsum         = _mm256_add_ps(velecsum,velec);
1197
1198             fscal            = felec;
1199
1200             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
1201
1202             /* Calculate temporary vectorial force */
1203             tx               = _mm256_mul_ps(fscal,dx23);
1204             ty               = _mm256_mul_ps(fscal,dy23);
1205             tz               = _mm256_mul_ps(fscal,dz23);
1206
1207             /* Update vectorial force */
1208             fix2             = _mm256_add_ps(fix2,tx);
1209             fiy2             = _mm256_add_ps(fiy2,ty);
1210             fiz2             = _mm256_add_ps(fiz2,tz);
1211
1212             fjx3             = _mm256_add_ps(fjx3,tx);
1213             fjy3             = _mm256_add_ps(fjy3,ty);
1214             fjz3             = _mm256_add_ps(fjz3,tz);
1215
1216             /**************************
1217              * CALCULATE INTERACTIONS *
1218              **************************/
1219
1220             r31              = _mm256_mul_ps(rsq31,rinv31);
1221             r31              = _mm256_andnot_ps(dummy_mask,r31);
1222
1223             /* EWALD ELECTROSTATICS */
1224             
1225             /* Analytical PME correction */
1226             zeta2            = _mm256_mul_ps(beta2,rsq31);
1227             rinv3            = _mm256_mul_ps(rinvsq31,rinv31);
1228             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
1229             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
1230             felec            = _mm256_mul_ps(qq31,felec);
1231             pmecorrV         = gmx_mm256_pmecorrV_ps(zeta2);
1232             pmecorrV         = _mm256_mul_ps(pmecorrV,beta);
1233             velec            = _mm256_sub_ps(rinv31,pmecorrV);
1234             velec            = _mm256_mul_ps(qq31,velec);
1235             
1236             /* Update potential sum for this i atom from the interaction with this j atom. */
1237             velec            = _mm256_andnot_ps(dummy_mask,velec);
1238             velecsum         = _mm256_add_ps(velecsum,velec);
1239
1240             fscal            = felec;
1241
1242             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
1243
1244             /* Calculate temporary vectorial force */
1245             tx               = _mm256_mul_ps(fscal,dx31);
1246             ty               = _mm256_mul_ps(fscal,dy31);
1247             tz               = _mm256_mul_ps(fscal,dz31);
1248
1249             /* Update vectorial force */
1250             fix3             = _mm256_add_ps(fix3,tx);
1251             fiy3             = _mm256_add_ps(fiy3,ty);
1252             fiz3             = _mm256_add_ps(fiz3,tz);
1253
1254             fjx1             = _mm256_add_ps(fjx1,tx);
1255             fjy1             = _mm256_add_ps(fjy1,ty);
1256             fjz1             = _mm256_add_ps(fjz1,tz);
1257
1258             /**************************
1259              * CALCULATE INTERACTIONS *
1260              **************************/
1261
1262             r32              = _mm256_mul_ps(rsq32,rinv32);
1263             r32              = _mm256_andnot_ps(dummy_mask,r32);
1264
1265             /* EWALD ELECTROSTATICS */
1266             
1267             /* Analytical PME correction */
1268             zeta2            = _mm256_mul_ps(beta2,rsq32);
1269             rinv3            = _mm256_mul_ps(rinvsq32,rinv32);
1270             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
1271             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
1272             felec            = _mm256_mul_ps(qq32,felec);
1273             pmecorrV         = gmx_mm256_pmecorrV_ps(zeta2);
1274             pmecorrV         = _mm256_mul_ps(pmecorrV,beta);
1275             velec            = _mm256_sub_ps(rinv32,pmecorrV);
1276             velec            = _mm256_mul_ps(qq32,velec);
1277             
1278             /* Update potential sum for this i atom from the interaction with this j atom. */
1279             velec            = _mm256_andnot_ps(dummy_mask,velec);
1280             velecsum         = _mm256_add_ps(velecsum,velec);
1281
1282             fscal            = felec;
1283
1284             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
1285
1286             /* Calculate temporary vectorial force */
1287             tx               = _mm256_mul_ps(fscal,dx32);
1288             ty               = _mm256_mul_ps(fscal,dy32);
1289             tz               = _mm256_mul_ps(fscal,dz32);
1290
1291             /* Update vectorial force */
1292             fix3             = _mm256_add_ps(fix3,tx);
1293             fiy3             = _mm256_add_ps(fiy3,ty);
1294             fiz3             = _mm256_add_ps(fiz3,tz);
1295
1296             fjx2             = _mm256_add_ps(fjx2,tx);
1297             fjy2             = _mm256_add_ps(fjy2,ty);
1298             fjz2             = _mm256_add_ps(fjz2,tz);
1299
1300             /**************************
1301              * CALCULATE INTERACTIONS *
1302              **************************/
1303
1304             r33              = _mm256_mul_ps(rsq33,rinv33);
1305             r33              = _mm256_andnot_ps(dummy_mask,r33);
1306
1307             /* EWALD ELECTROSTATICS */
1308             
1309             /* Analytical PME correction */
1310             zeta2            = _mm256_mul_ps(beta2,rsq33);
1311             rinv3            = _mm256_mul_ps(rinvsq33,rinv33);
1312             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
1313             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
1314             felec            = _mm256_mul_ps(qq33,felec);
1315             pmecorrV         = gmx_mm256_pmecorrV_ps(zeta2);
1316             pmecorrV         = _mm256_mul_ps(pmecorrV,beta);
1317             velec            = _mm256_sub_ps(rinv33,pmecorrV);
1318             velec            = _mm256_mul_ps(qq33,velec);
1319             
1320             /* Update potential sum for this i atom from the interaction with this j atom. */
1321             velec            = _mm256_andnot_ps(dummy_mask,velec);
1322             velecsum         = _mm256_add_ps(velecsum,velec);
1323
1324             fscal            = felec;
1325
1326             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
1327
1328             /* Calculate temporary vectorial force */
1329             tx               = _mm256_mul_ps(fscal,dx33);
1330             ty               = _mm256_mul_ps(fscal,dy33);
1331             tz               = _mm256_mul_ps(fscal,dz33);
1332
1333             /* Update vectorial force */
1334             fix3             = _mm256_add_ps(fix3,tx);
1335             fiy3             = _mm256_add_ps(fiy3,ty);
1336             fiz3             = _mm256_add_ps(fiz3,tz);
1337
1338             fjx3             = _mm256_add_ps(fjx3,tx);
1339             fjy3             = _mm256_add_ps(fjy3,ty);
1340             fjz3             = _mm256_add_ps(fjz3,tz);
1341
1342             fjptrA             = (jnrlistA>=0) ? f+j_coord_offsetA : scratch;
1343             fjptrB             = (jnrlistB>=0) ? f+j_coord_offsetB : scratch;
1344             fjptrC             = (jnrlistC>=0) ? f+j_coord_offsetC : scratch;
1345             fjptrD             = (jnrlistD>=0) ? f+j_coord_offsetD : scratch;
1346             fjptrE             = (jnrlistE>=0) ? f+j_coord_offsetE : scratch;
1347             fjptrF             = (jnrlistF>=0) ? f+j_coord_offsetF : scratch;
1348             fjptrG             = (jnrlistG>=0) ? f+j_coord_offsetG : scratch;
1349             fjptrH             = (jnrlistH>=0) ? f+j_coord_offsetH : scratch;
1350
1351             gmx_mm256_decrement_4rvec_8ptr_swizzle_ps(fjptrA,fjptrB,fjptrC,fjptrD,fjptrE,fjptrF,fjptrG,fjptrH,
1352                                                       fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,
1353                                                       fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
1354
1355             /* Inner loop uses 825 flops */
1356         }
1357
1358         /* End of innermost loop */
1359
1360         gmx_mm256_update_iforce_4atom_swizzle_ps(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
1361                                                  f+i_coord_offset,fshift+i_shift_offset);
1362
1363         ggid                        = gid[iidx];
1364         /* Update potential energies */
1365         gmx_mm256_update_1pot_ps(velecsum,kernel_data->energygrp_elec+ggid);
1366         gmx_mm256_update_1pot_ps(vvdwsum,kernel_data->energygrp_vdw+ggid);
1367
1368         /* Increment number of inner iterations */
1369         inneriter                  += j_index_end - j_index_start;
1370
1371         /* Outer loop uses 26 flops */
1372     }
1373
1374     /* Increment number of outer iterations */
1375     outeriter        += nri;
1376
1377     /* Update outer/inner flops */
1378
1379     inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_VF,outeriter*26 + inneriter*825);
1380 }
1381 /*
1382  * Gromacs nonbonded kernel:   nb_kernel_ElecEw_VdwCSTab_GeomW4W4_F_avx_256_single
1383  * Electrostatics interaction: Ewald
1384  * VdW interaction:            CubicSplineTable
1385  * Geometry:                   Water4-Water4
1386  * Calculate force/pot:        Force
1387  */
1388 void
1389 nb_kernel_ElecEw_VdwCSTab_GeomW4W4_F_avx_256_single
1390                     (t_nblist * gmx_restrict                nlist,
1391                      rvec * gmx_restrict                    xx,
1392                      rvec * gmx_restrict                    ff,
1393                      t_forcerec * gmx_restrict              fr,
1394                      t_mdatoms * gmx_restrict               mdatoms,
1395                      nb_kernel_data_t * gmx_restrict        kernel_data,
1396                      t_nrnb * gmx_restrict                  nrnb)
1397 {
1398     /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or 
1399      * just 0 for non-waters.
1400      * Suffixes A,B,C,D,E,F,G,H refer to j loop unrolling done with AVX, e.g. for the eight different
1401      * jnr indices corresponding to data put in the four positions in the SIMD register.
1402      */
1403     int              i_shift_offset,i_coord_offset,outeriter,inneriter;
1404     int              j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
1405     int              jnrA,jnrB,jnrC,jnrD;
1406     int              jnrE,jnrF,jnrG,jnrH;
1407     int              jnrlistA,jnrlistB,jnrlistC,jnrlistD;
1408     int              jnrlistE,jnrlistF,jnrlistG,jnrlistH;
1409     int              j_coord_offsetA,j_coord_offsetB,j_coord_offsetC,j_coord_offsetD;
1410     int              j_coord_offsetE,j_coord_offsetF,j_coord_offsetG,j_coord_offsetH;
1411     int              *iinr,*jindex,*jjnr,*shiftidx,*gid;
1412     real             rcutoff_scalar;
1413     real             *shiftvec,*fshift,*x,*f;
1414     real             *fjptrA,*fjptrB,*fjptrC,*fjptrD,*fjptrE,*fjptrF,*fjptrG,*fjptrH;
1415     real             scratch[4*DIM];
1416     __m256           tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
1417     real *           vdwioffsetptr0;
1418     __m256           ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
1419     real *           vdwioffsetptr1;
1420     __m256           ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
1421     real *           vdwioffsetptr2;
1422     __m256           ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
1423     real *           vdwioffsetptr3;
1424     __m256           ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
1425     int              vdwjidx0A,vdwjidx0B,vdwjidx0C,vdwjidx0D,vdwjidx0E,vdwjidx0F,vdwjidx0G,vdwjidx0H;
1426     __m256           jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
1427     int              vdwjidx1A,vdwjidx1B,vdwjidx1C,vdwjidx1D,vdwjidx1E,vdwjidx1F,vdwjidx1G,vdwjidx1H;
1428     __m256           jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
1429     int              vdwjidx2A,vdwjidx2B,vdwjidx2C,vdwjidx2D,vdwjidx2E,vdwjidx2F,vdwjidx2G,vdwjidx2H;
1430     __m256           jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
1431     int              vdwjidx3A,vdwjidx3B,vdwjidx3C,vdwjidx3D,vdwjidx3E,vdwjidx3F,vdwjidx3G,vdwjidx3H;
1432     __m256           jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
1433     __m256           dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
1434     __m256           dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
1435     __m256           dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
1436     __m256           dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
1437     __m256           dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
1438     __m256           dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
1439     __m256           dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
1440     __m256           dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
1441     __m256           dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
1442     __m256           dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
1443     __m256           velec,felec,velecsum,facel,crf,krf,krf2;
1444     real             *charge;
1445     int              nvdwtype;
1446     __m256           rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
1447     int              *vdwtype;
1448     real             *vdwparam;
1449     __m256           one_sixth   = _mm256_set1_ps(1.0/6.0);
1450     __m256           one_twelfth = _mm256_set1_ps(1.0/12.0);
1451     __m256i          vfitab;
1452     __m128i          vfitab_lo,vfitab_hi;
1453     __m128i          ifour       = _mm_set1_epi32(4);
1454     __m256           rt,vfeps,vftabscale,Y,F,G,H,Heps,Fp,VV,FF;
1455     real             *vftab;
1456     __m256i          ewitab;
1457     __m128i          ewitab_lo,ewitab_hi;
1458     __m256           ewtabscale,eweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
1459     __m256           beta,beta2,beta3,zeta2,pmecorrF,pmecorrV,rinv3;
1460     real             *ewtab;
1461     __m256           dummy_mask,cutoff_mask;
1462     __m256           signbit = _mm256_castsi256_ps( _mm256_set1_epi32(0x80000000) );
1463     __m256           one     = _mm256_set1_ps(1.0);
1464     __m256           two     = _mm256_set1_ps(2.0);
1465     x                = xx[0];
1466     f                = ff[0];
1467
1468     nri              = nlist->nri;
1469     iinr             = nlist->iinr;
1470     jindex           = nlist->jindex;
1471     jjnr             = nlist->jjnr;
1472     shiftidx         = nlist->shift;
1473     gid              = nlist->gid;
1474     shiftvec         = fr->shift_vec[0];
1475     fshift           = fr->fshift[0];
1476     facel            = _mm256_set1_ps(fr->epsfac);
1477     charge           = mdatoms->chargeA;
1478     nvdwtype         = fr->ntype;
1479     vdwparam         = fr->nbfp;
1480     vdwtype          = mdatoms->typeA;
1481
1482     vftab            = kernel_data->table_vdw->data;
1483     vftabscale       = _mm256_set1_ps(kernel_data->table_vdw->scale);
1484
1485     sh_ewald         = _mm256_set1_ps(fr->ic->sh_ewald);
1486     beta             = _mm256_set1_ps(fr->ic->ewaldcoeff);
1487     beta2            = _mm256_mul_ps(beta,beta);
1488     beta3            = _mm256_mul_ps(beta,beta2);
1489
1490     ewtab            = fr->ic->tabq_coul_F;
1491     ewtabscale       = _mm256_set1_ps(fr->ic->tabq_scale);
1492     ewtabhalfspace   = _mm256_set1_ps(0.5/fr->ic->tabq_scale);
1493
1494     /* Setup water-specific parameters */
1495     inr              = nlist->iinr[0];
1496     iq1              = _mm256_mul_ps(facel,_mm256_set1_ps(charge[inr+1]));
1497     iq2              = _mm256_mul_ps(facel,_mm256_set1_ps(charge[inr+2]));
1498     iq3              = _mm256_mul_ps(facel,_mm256_set1_ps(charge[inr+3]));
1499     vdwioffsetptr0   = vdwparam+2*nvdwtype*vdwtype[inr+0];
1500
1501     jq1              = _mm256_set1_ps(charge[inr+1]);
1502     jq2              = _mm256_set1_ps(charge[inr+2]);
1503     jq3              = _mm256_set1_ps(charge[inr+3]);
1504     vdwjidx0A        = 2*vdwtype[inr+0];
1505     c6_00            = _mm256_set1_ps(vdwioffsetptr0[vdwjidx0A]);
1506     c12_00           = _mm256_set1_ps(vdwioffsetptr0[vdwjidx0A+1]);
1507     qq11             = _mm256_mul_ps(iq1,jq1);
1508     qq12             = _mm256_mul_ps(iq1,jq2);
1509     qq13             = _mm256_mul_ps(iq1,jq3);
1510     qq21             = _mm256_mul_ps(iq2,jq1);
1511     qq22             = _mm256_mul_ps(iq2,jq2);
1512     qq23             = _mm256_mul_ps(iq2,jq3);
1513     qq31             = _mm256_mul_ps(iq3,jq1);
1514     qq32             = _mm256_mul_ps(iq3,jq2);
1515     qq33             = _mm256_mul_ps(iq3,jq3);
1516
1517     /* Avoid stupid compiler warnings */
1518     jnrA = jnrB = jnrC = jnrD = jnrE = jnrF = jnrG = jnrH = 0;
1519     j_coord_offsetA = 0;
1520     j_coord_offsetB = 0;
1521     j_coord_offsetC = 0;
1522     j_coord_offsetD = 0;
1523     j_coord_offsetE = 0;
1524     j_coord_offsetF = 0;
1525     j_coord_offsetG = 0;
1526     j_coord_offsetH = 0;
1527
1528     outeriter        = 0;
1529     inneriter        = 0;
1530
1531     for(iidx=0;iidx<4*DIM;iidx++)
1532     {
1533         scratch[iidx] = 0.0;
1534     }
1535
1536     /* Start outer loop over neighborlists */
1537     for(iidx=0; iidx<nri; iidx++)
1538     {
1539         /* Load shift vector for this list */
1540         i_shift_offset   = DIM*shiftidx[iidx];
1541
1542         /* Load limits for loop over neighbors */
1543         j_index_start    = jindex[iidx];
1544         j_index_end      = jindex[iidx+1];
1545
1546         /* Get outer coordinate index */
1547         inr              = iinr[iidx];
1548         i_coord_offset   = DIM*inr;
1549
1550         /* Load i particle coords and add shift vector */
1551         gmx_mm256_load_shift_and_4rvec_broadcast_ps(shiftvec+i_shift_offset,x+i_coord_offset,
1552                                                     &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
1553
1554         fix0             = _mm256_setzero_ps();
1555         fiy0             = _mm256_setzero_ps();
1556         fiz0             = _mm256_setzero_ps();
1557         fix1             = _mm256_setzero_ps();
1558         fiy1             = _mm256_setzero_ps();
1559         fiz1             = _mm256_setzero_ps();
1560         fix2             = _mm256_setzero_ps();
1561         fiy2             = _mm256_setzero_ps();
1562         fiz2             = _mm256_setzero_ps();
1563         fix3             = _mm256_setzero_ps();
1564         fiy3             = _mm256_setzero_ps();
1565         fiz3             = _mm256_setzero_ps();
1566
1567         /* Start inner kernel loop */
1568         for(jidx=j_index_start; jidx<j_index_end && jjnr[jidx+7]>=0; jidx+=8)
1569         {
1570
1571             /* Get j neighbor index, and coordinate index */
1572             jnrA             = jjnr[jidx];
1573             jnrB             = jjnr[jidx+1];
1574             jnrC             = jjnr[jidx+2];
1575             jnrD             = jjnr[jidx+3];
1576             jnrE             = jjnr[jidx+4];
1577             jnrF             = jjnr[jidx+5];
1578             jnrG             = jjnr[jidx+6];
1579             jnrH             = jjnr[jidx+7];
1580             j_coord_offsetA  = DIM*jnrA;
1581             j_coord_offsetB  = DIM*jnrB;
1582             j_coord_offsetC  = DIM*jnrC;
1583             j_coord_offsetD  = DIM*jnrD;
1584             j_coord_offsetE  = DIM*jnrE;
1585             j_coord_offsetF  = DIM*jnrF;
1586             j_coord_offsetG  = DIM*jnrG;
1587             j_coord_offsetH  = DIM*jnrH;
1588
1589             /* load j atom coordinates */
1590             gmx_mm256_load_4rvec_8ptr_swizzle_ps(x+j_coord_offsetA,x+j_coord_offsetB,
1591                                                  x+j_coord_offsetC,x+j_coord_offsetD,
1592                                                  x+j_coord_offsetE,x+j_coord_offsetF,
1593                                                  x+j_coord_offsetG,x+j_coord_offsetH,
1594                                                  &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
1595                                                  &jy2,&jz2,&jx3,&jy3,&jz3);
1596
1597             /* Calculate displacement vector */
1598             dx00             = _mm256_sub_ps(ix0,jx0);
1599             dy00             = _mm256_sub_ps(iy0,jy0);
1600             dz00             = _mm256_sub_ps(iz0,jz0);
1601             dx11             = _mm256_sub_ps(ix1,jx1);
1602             dy11             = _mm256_sub_ps(iy1,jy1);
1603             dz11             = _mm256_sub_ps(iz1,jz1);
1604             dx12             = _mm256_sub_ps(ix1,jx2);
1605             dy12             = _mm256_sub_ps(iy1,jy2);
1606             dz12             = _mm256_sub_ps(iz1,jz2);
1607             dx13             = _mm256_sub_ps(ix1,jx3);
1608             dy13             = _mm256_sub_ps(iy1,jy3);
1609             dz13             = _mm256_sub_ps(iz1,jz3);
1610             dx21             = _mm256_sub_ps(ix2,jx1);
1611             dy21             = _mm256_sub_ps(iy2,jy1);
1612             dz21             = _mm256_sub_ps(iz2,jz1);
1613             dx22             = _mm256_sub_ps(ix2,jx2);
1614             dy22             = _mm256_sub_ps(iy2,jy2);
1615             dz22             = _mm256_sub_ps(iz2,jz2);
1616             dx23             = _mm256_sub_ps(ix2,jx3);
1617             dy23             = _mm256_sub_ps(iy2,jy3);
1618             dz23             = _mm256_sub_ps(iz2,jz3);
1619             dx31             = _mm256_sub_ps(ix3,jx1);
1620             dy31             = _mm256_sub_ps(iy3,jy1);
1621             dz31             = _mm256_sub_ps(iz3,jz1);
1622             dx32             = _mm256_sub_ps(ix3,jx2);
1623             dy32             = _mm256_sub_ps(iy3,jy2);
1624             dz32             = _mm256_sub_ps(iz3,jz2);
1625             dx33             = _mm256_sub_ps(ix3,jx3);
1626             dy33             = _mm256_sub_ps(iy3,jy3);
1627             dz33             = _mm256_sub_ps(iz3,jz3);
1628
1629             /* Calculate squared distance and things based on it */
1630             rsq00            = gmx_mm256_calc_rsq_ps(dx00,dy00,dz00);
1631             rsq11            = gmx_mm256_calc_rsq_ps(dx11,dy11,dz11);
1632             rsq12            = gmx_mm256_calc_rsq_ps(dx12,dy12,dz12);
1633             rsq13            = gmx_mm256_calc_rsq_ps(dx13,dy13,dz13);
1634             rsq21            = gmx_mm256_calc_rsq_ps(dx21,dy21,dz21);
1635             rsq22            = gmx_mm256_calc_rsq_ps(dx22,dy22,dz22);
1636             rsq23            = gmx_mm256_calc_rsq_ps(dx23,dy23,dz23);
1637             rsq31            = gmx_mm256_calc_rsq_ps(dx31,dy31,dz31);
1638             rsq32            = gmx_mm256_calc_rsq_ps(dx32,dy32,dz32);
1639             rsq33            = gmx_mm256_calc_rsq_ps(dx33,dy33,dz33);
1640
1641             rinv00           = gmx_mm256_invsqrt_ps(rsq00);
1642             rinv11           = gmx_mm256_invsqrt_ps(rsq11);
1643             rinv12           = gmx_mm256_invsqrt_ps(rsq12);
1644             rinv13           = gmx_mm256_invsqrt_ps(rsq13);
1645             rinv21           = gmx_mm256_invsqrt_ps(rsq21);
1646             rinv22           = gmx_mm256_invsqrt_ps(rsq22);
1647             rinv23           = gmx_mm256_invsqrt_ps(rsq23);
1648             rinv31           = gmx_mm256_invsqrt_ps(rsq31);
1649             rinv32           = gmx_mm256_invsqrt_ps(rsq32);
1650             rinv33           = gmx_mm256_invsqrt_ps(rsq33);
1651
1652             rinvsq11         = _mm256_mul_ps(rinv11,rinv11);
1653             rinvsq12         = _mm256_mul_ps(rinv12,rinv12);
1654             rinvsq13         = _mm256_mul_ps(rinv13,rinv13);
1655             rinvsq21         = _mm256_mul_ps(rinv21,rinv21);
1656             rinvsq22         = _mm256_mul_ps(rinv22,rinv22);
1657             rinvsq23         = _mm256_mul_ps(rinv23,rinv23);
1658             rinvsq31         = _mm256_mul_ps(rinv31,rinv31);
1659             rinvsq32         = _mm256_mul_ps(rinv32,rinv32);
1660             rinvsq33         = _mm256_mul_ps(rinv33,rinv33);
1661
1662             fjx0             = _mm256_setzero_ps();
1663             fjy0             = _mm256_setzero_ps();
1664             fjz0             = _mm256_setzero_ps();
1665             fjx1             = _mm256_setzero_ps();
1666             fjy1             = _mm256_setzero_ps();
1667             fjz1             = _mm256_setzero_ps();
1668             fjx2             = _mm256_setzero_ps();
1669             fjy2             = _mm256_setzero_ps();
1670             fjz2             = _mm256_setzero_ps();
1671             fjx3             = _mm256_setzero_ps();
1672             fjy3             = _mm256_setzero_ps();
1673             fjz3             = _mm256_setzero_ps();
1674
1675             /**************************
1676              * CALCULATE INTERACTIONS *
1677              **************************/
1678
1679             r00              = _mm256_mul_ps(rsq00,rinv00);
1680
1681             /* Calculate table index by multiplying r with table scale and truncate to integer */
1682             rt               = _mm256_mul_ps(r00,vftabscale);
1683             vfitab           = _mm256_cvttps_epi32(rt);
1684             vfeps            = _mm256_sub_ps(rt,_mm256_round_ps(rt, _MM_FROUND_FLOOR));
1685             /*         AVX1 does not support 256-bit integer operations, so now we go to 128-bit mode... */
1686             vfitab_lo        = _mm256_extractf128_si256(vfitab,0x0);
1687             vfitab_hi        = _mm256_extractf128_si256(vfitab,0x1);
1688             vfitab_lo        = _mm_slli_epi32(vfitab_lo,3);
1689             vfitab_hi        = _mm_slli_epi32(vfitab_hi,3);
1690
1691             /* CUBIC SPLINE TABLE DISPERSION */
1692             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
1693                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
1694             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
1695                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
1696             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
1697                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
1698             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
1699                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
1700             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
1701             Heps             = _mm256_mul_ps(vfeps,H);
1702             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
1703             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
1704             fvdw6            = _mm256_mul_ps(c6_00,FF);
1705
1706             /* CUBIC SPLINE TABLE REPULSION */
1707             vfitab_lo        = _mm_add_epi32(vfitab_lo,ifour);
1708             vfitab_hi        = _mm_add_epi32(vfitab_hi,ifour);
1709             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
1710                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
1711             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
1712                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
1713             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
1714                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
1715             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
1716                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
1717             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
1718             Heps             = _mm256_mul_ps(vfeps,H);
1719             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
1720             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
1721             fvdw12           = _mm256_mul_ps(c12_00,FF);
1722             fvdw             = _mm256_xor_ps(signbit,_mm256_mul_ps(_mm256_add_ps(fvdw6,fvdw12),_mm256_mul_ps(vftabscale,rinv00)));
1723
1724             fscal            = fvdw;
1725
1726             /* Calculate temporary vectorial force */
1727             tx               = _mm256_mul_ps(fscal,dx00);
1728             ty               = _mm256_mul_ps(fscal,dy00);
1729             tz               = _mm256_mul_ps(fscal,dz00);
1730
1731             /* Update vectorial force */
1732             fix0             = _mm256_add_ps(fix0,tx);
1733             fiy0             = _mm256_add_ps(fiy0,ty);
1734             fiz0             = _mm256_add_ps(fiz0,tz);
1735
1736             fjx0             = _mm256_add_ps(fjx0,tx);
1737             fjy0             = _mm256_add_ps(fjy0,ty);
1738             fjz0             = _mm256_add_ps(fjz0,tz);
1739
1740             /**************************
1741              * CALCULATE INTERACTIONS *
1742              **************************/
1743
1744             r11              = _mm256_mul_ps(rsq11,rinv11);
1745
1746             /* EWALD ELECTROSTATICS */
1747             
1748             /* Analytical PME correction */
1749             zeta2            = _mm256_mul_ps(beta2,rsq11);
1750             rinv3            = _mm256_mul_ps(rinvsq11,rinv11);
1751             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
1752             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
1753             felec            = _mm256_mul_ps(qq11,felec);
1754             
1755             fscal            = felec;
1756
1757             /* Calculate temporary vectorial force */
1758             tx               = _mm256_mul_ps(fscal,dx11);
1759             ty               = _mm256_mul_ps(fscal,dy11);
1760             tz               = _mm256_mul_ps(fscal,dz11);
1761
1762             /* Update vectorial force */
1763             fix1             = _mm256_add_ps(fix1,tx);
1764             fiy1             = _mm256_add_ps(fiy1,ty);
1765             fiz1             = _mm256_add_ps(fiz1,tz);
1766
1767             fjx1             = _mm256_add_ps(fjx1,tx);
1768             fjy1             = _mm256_add_ps(fjy1,ty);
1769             fjz1             = _mm256_add_ps(fjz1,tz);
1770
1771             /**************************
1772              * CALCULATE INTERACTIONS *
1773              **************************/
1774
1775             r12              = _mm256_mul_ps(rsq12,rinv12);
1776
1777             /* EWALD ELECTROSTATICS */
1778             
1779             /* Analytical PME correction */
1780             zeta2            = _mm256_mul_ps(beta2,rsq12);
1781             rinv3            = _mm256_mul_ps(rinvsq12,rinv12);
1782             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
1783             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
1784             felec            = _mm256_mul_ps(qq12,felec);
1785             
1786             fscal            = felec;
1787
1788             /* Calculate temporary vectorial force */
1789             tx               = _mm256_mul_ps(fscal,dx12);
1790             ty               = _mm256_mul_ps(fscal,dy12);
1791             tz               = _mm256_mul_ps(fscal,dz12);
1792
1793             /* Update vectorial force */
1794             fix1             = _mm256_add_ps(fix1,tx);
1795             fiy1             = _mm256_add_ps(fiy1,ty);
1796             fiz1             = _mm256_add_ps(fiz1,tz);
1797
1798             fjx2             = _mm256_add_ps(fjx2,tx);
1799             fjy2             = _mm256_add_ps(fjy2,ty);
1800             fjz2             = _mm256_add_ps(fjz2,tz);
1801
1802             /**************************
1803              * CALCULATE INTERACTIONS *
1804              **************************/
1805
1806             r13              = _mm256_mul_ps(rsq13,rinv13);
1807
1808             /* EWALD ELECTROSTATICS */
1809             
1810             /* Analytical PME correction */
1811             zeta2            = _mm256_mul_ps(beta2,rsq13);
1812             rinv3            = _mm256_mul_ps(rinvsq13,rinv13);
1813             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
1814             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
1815             felec            = _mm256_mul_ps(qq13,felec);
1816             
1817             fscal            = felec;
1818
1819             /* Calculate temporary vectorial force */
1820             tx               = _mm256_mul_ps(fscal,dx13);
1821             ty               = _mm256_mul_ps(fscal,dy13);
1822             tz               = _mm256_mul_ps(fscal,dz13);
1823
1824             /* Update vectorial force */
1825             fix1             = _mm256_add_ps(fix1,tx);
1826             fiy1             = _mm256_add_ps(fiy1,ty);
1827             fiz1             = _mm256_add_ps(fiz1,tz);
1828
1829             fjx3             = _mm256_add_ps(fjx3,tx);
1830             fjy3             = _mm256_add_ps(fjy3,ty);
1831             fjz3             = _mm256_add_ps(fjz3,tz);
1832
1833             /**************************
1834              * CALCULATE INTERACTIONS *
1835              **************************/
1836
1837             r21              = _mm256_mul_ps(rsq21,rinv21);
1838
1839             /* EWALD ELECTROSTATICS */
1840             
1841             /* Analytical PME correction */
1842             zeta2            = _mm256_mul_ps(beta2,rsq21);
1843             rinv3            = _mm256_mul_ps(rinvsq21,rinv21);
1844             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
1845             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
1846             felec            = _mm256_mul_ps(qq21,felec);
1847             
1848             fscal            = felec;
1849
1850             /* Calculate temporary vectorial force */
1851             tx               = _mm256_mul_ps(fscal,dx21);
1852             ty               = _mm256_mul_ps(fscal,dy21);
1853             tz               = _mm256_mul_ps(fscal,dz21);
1854
1855             /* Update vectorial force */
1856             fix2             = _mm256_add_ps(fix2,tx);
1857             fiy2             = _mm256_add_ps(fiy2,ty);
1858             fiz2             = _mm256_add_ps(fiz2,tz);
1859
1860             fjx1             = _mm256_add_ps(fjx1,tx);
1861             fjy1             = _mm256_add_ps(fjy1,ty);
1862             fjz1             = _mm256_add_ps(fjz1,tz);
1863
1864             /**************************
1865              * CALCULATE INTERACTIONS *
1866              **************************/
1867
1868             r22              = _mm256_mul_ps(rsq22,rinv22);
1869
1870             /* EWALD ELECTROSTATICS */
1871             
1872             /* Analytical PME correction */
1873             zeta2            = _mm256_mul_ps(beta2,rsq22);
1874             rinv3            = _mm256_mul_ps(rinvsq22,rinv22);
1875             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
1876             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
1877             felec            = _mm256_mul_ps(qq22,felec);
1878             
1879             fscal            = felec;
1880
1881             /* Calculate temporary vectorial force */
1882             tx               = _mm256_mul_ps(fscal,dx22);
1883             ty               = _mm256_mul_ps(fscal,dy22);
1884             tz               = _mm256_mul_ps(fscal,dz22);
1885
1886             /* Update vectorial force */
1887             fix2             = _mm256_add_ps(fix2,tx);
1888             fiy2             = _mm256_add_ps(fiy2,ty);
1889             fiz2             = _mm256_add_ps(fiz2,tz);
1890
1891             fjx2             = _mm256_add_ps(fjx2,tx);
1892             fjy2             = _mm256_add_ps(fjy2,ty);
1893             fjz2             = _mm256_add_ps(fjz2,tz);
1894
1895             /**************************
1896              * CALCULATE INTERACTIONS *
1897              **************************/
1898
1899             r23              = _mm256_mul_ps(rsq23,rinv23);
1900
1901             /* EWALD ELECTROSTATICS */
1902             
1903             /* Analytical PME correction */
1904             zeta2            = _mm256_mul_ps(beta2,rsq23);
1905             rinv3            = _mm256_mul_ps(rinvsq23,rinv23);
1906             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
1907             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
1908             felec            = _mm256_mul_ps(qq23,felec);
1909             
1910             fscal            = felec;
1911
1912             /* Calculate temporary vectorial force */
1913             tx               = _mm256_mul_ps(fscal,dx23);
1914             ty               = _mm256_mul_ps(fscal,dy23);
1915             tz               = _mm256_mul_ps(fscal,dz23);
1916
1917             /* Update vectorial force */
1918             fix2             = _mm256_add_ps(fix2,tx);
1919             fiy2             = _mm256_add_ps(fiy2,ty);
1920             fiz2             = _mm256_add_ps(fiz2,tz);
1921
1922             fjx3             = _mm256_add_ps(fjx3,tx);
1923             fjy3             = _mm256_add_ps(fjy3,ty);
1924             fjz3             = _mm256_add_ps(fjz3,tz);
1925
1926             /**************************
1927              * CALCULATE INTERACTIONS *
1928              **************************/
1929
1930             r31              = _mm256_mul_ps(rsq31,rinv31);
1931
1932             /* EWALD ELECTROSTATICS */
1933             
1934             /* Analytical PME correction */
1935             zeta2            = _mm256_mul_ps(beta2,rsq31);
1936             rinv3            = _mm256_mul_ps(rinvsq31,rinv31);
1937             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
1938             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
1939             felec            = _mm256_mul_ps(qq31,felec);
1940             
1941             fscal            = felec;
1942
1943             /* Calculate temporary vectorial force */
1944             tx               = _mm256_mul_ps(fscal,dx31);
1945             ty               = _mm256_mul_ps(fscal,dy31);
1946             tz               = _mm256_mul_ps(fscal,dz31);
1947
1948             /* Update vectorial force */
1949             fix3             = _mm256_add_ps(fix3,tx);
1950             fiy3             = _mm256_add_ps(fiy3,ty);
1951             fiz3             = _mm256_add_ps(fiz3,tz);
1952
1953             fjx1             = _mm256_add_ps(fjx1,tx);
1954             fjy1             = _mm256_add_ps(fjy1,ty);
1955             fjz1             = _mm256_add_ps(fjz1,tz);
1956
1957             /**************************
1958              * CALCULATE INTERACTIONS *
1959              **************************/
1960
1961             r32              = _mm256_mul_ps(rsq32,rinv32);
1962
1963             /* EWALD ELECTROSTATICS */
1964             
1965             /* Analytical PME correction */
1966             zeta2            = _mm256_mul_ps(beta2,rsq32);
1967             rinv3            = _mm256_mul_ps(rinvsq32,rinv32);
1968             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
1969             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
1970             felec            = _mm256_mul_ps(qq32,felec);
1971             
1972             fscal            = felec;
1973
1974             /* Calculate temporary vectorial force */
1975             tx               = _mm256_mul_ps(fscal,dx32);
1976             ty               = _mm256_mul_ps(fscal,dy32);
1977             tz               = _mm256_mul_ps(fscal,dz32);
1978
1979             /* Update vectorial force */
1980             fix3             = _mm256_add_ps(fix3,tx);
1981             fiy3             = _mm256_add_ps(fiy3,ty);
1982             fiz3             = _mm256_add_ps(fiz3,tz);
1983
1984             fjx2             = _mm256_add_ps(fjx2,tx);
1985             fjy2             = _mm256_add_ps(fjy2,ty);
1986             fjz2             = _mm256_add_ps(fjz2,tz);
1987
1988             /**************************
1989              * CALCULATE INTERACTIONS *
1990              **************************/
1991
1992             r33              = _mm256_mul_ps(rsq33,rinv33);
1993
1994             /* EWALD ELECTROSTATICS */
1995             
1996             /* Analytical PME correction */
1997             zeta2            = _mm256_mul_ps(beta2,rsq33);
1998             rinv3            = _mm256_mul_ps(rinvsq33,rinv33);
1999             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
2000             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
2001             felec            = _mm256_mul_ps(qq33,felec);
2002             
2003             fscal            = felec;
2004
2005             /* Calculate temporary vectorial force */
2006             tx               = _mm256_mul_ps(fscal,dx33);
2007             ty               = _mm256_mul_ps(fscal,dy33);
2008             tz               = _mm256_mul_ps(fscal,dz33);
2009
2010             /* Update vectorial force */
2011             fix3             = _mm256_add_ps(fix3,tx);
2012             fiy3             = _mm256_add_ps(fiy3,ty);
2013             fiz3             = _mm256_add_ps(fiz3,tz);
2014
2015             fjx3             = _mm256_add_ps(fjx3,tx);
2016             fjy3             = _mm256_add_ps(fjy3,ty);
2017             fjz3             = _mm256_add_ps(fjz3,tz);
2018
2019             fjptrA             = f+j_coord_offsetA;
2020             fjptrB             = f+j_coord_offsetB;
2021             fjptrC             = f+j_coord_offsetC;
2022             fjptrD             = f+j_coord_offsetD;
2023             fjptrE             = f+j_coord_offsetE;
2024             fjptrF             = f+j_coord_offsetF;
2025             fjptrG             = f+j_coord_offsetG;
2026             fjptrH             = f+j_coord_offsetH;
2027
2028             gmx_mm256_decrement_4rvec_8ptr_swizzle_ps(fjptrA,fjptrB,fjptrC,fjptrD,fjptrE,fjptrF,fjptrG,fjptrH,
2029                                                       fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,
2030                                                       fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
2031
2032             /* Inner loop uses 555 flops */
2033         }
2034
2035         if(jidx<j_index_end)
2036         {
2037
2038             /* Get j neighbor index, and coordinate index */
2039             jnrlistA         = jjnr[jidx];
2040             jnrlistB         = jjnr[jidx+1];
2041             jnrlistC         = jjnr[jidx+2];
2042             jnrlistD         = jjnr[jidx+3];
2043             jnrlistE         = jjnr[jidx+4];
2044             jnrlistF         = jjnr[jidx+5];
2045             jnrlistG         = jjnr[jidx+6];
2046             jnrlistH         = jjnr[jidx+7];
2047             /* Sign of each element will be negative for non-real atoms.
2048              * This mask will be 0xFFFFFFFF for dummy entries and 0x0 for real ones,
2049              * so use it as val = _mm_andnot_ps(mask,val) to clear dummy entries.
2050              */
2051             dummy_mask = gmx_mm256_set_m128(gmx_mm_castsi128_ps(_mm_cmplt_epi32(_mm_loadu_si128((const __m128i *)(jjnr+jidx+4)),_mm_setzero_si128())),
2052                                             gmx_mm_castsi128_ps(_mm_cmplt_epi32(_mm_loadu_si128((const __m128i *)(jjnr+jidx)),_mm_setzero_si128())));
2053                                             
2054             jnrA       = (jnrlistA>=0) ? jnrlistA : 0;
2055             jnrB       = (jnrlistB>=0) ? jnrlistB : 0;
2056             jnrC       = (jnrlistC>=0) ? jnrlistC : 0;
2057             jnrD       = (jnrlistD>=0) ? jnrlistD : 0;
2058             jnrE       = (jnrlistE>=0) ? jnrlistE : 0;
2059             jnrF       = (jnrlistF>=0) ? jnrlistF : 0;
2060             jnrG       = (jnrlistG>=0) ? jnrlistG : 0;
2061             jnrH       = (jnrlistH>=0) ? jnrlistH : 0;
2062             j_coord_offsetA  = DIM*jnrA;
2063             j_coord_offsetB  = DIM*jnrB;
2064             j_coord_offsetC  = DIM*jnrC;
2065             j_coord_offsetD  = DIM*jnrD;
2066             j_coord_offsetE  = DIM*jnrE;
2067             j_coord_offsetF  = DIM*jnrF;
2068             j_coord_offsetG  = DIM*jnrG;
2069             j_coord_offsetH  = DIM*jnrH;
2070
2071             /* load j atom coordinates */
2072             gmx_mm256_load_4rvec_8ptr_swizzle_ps(x+j_coord_offsetA,x+j_coord_offsetB,
2073                                                  x+j_coord_offsetC,x+j_coord_offsetD,
2074                                                  x+j_coord_offsetE,x+j_coord_offsetF,
2075                                                  x+j_coord_offsetG,x+j_coord_offsetH,
2076                                                  &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
2077                                                  &jy2,&jz2,&jx3,&jy3,&jz3);
2078
2079             /* Calculate displacement vector */
2080             dx00             = _mm256_sub_ps(ix0,jx0);
2081             dy00             = _mm256_sub_ps(iy0,jy0);
2082             dz00             = _mm256_sub_ps(iz0,jz0);
2083             dx11             = _mm256_sub_ps(ix1,jx1);
2084             dy11             = _mm256_sub_ps(iy1,jy1);
2085             dz11             = _mm256_sub_ps(iz1,jz1);
2086             dx12             = _mm256_sub_ps(ix1,jx2);
2087             dy12             = _mm256_sub_ps(iy1,jy2);
2088             dz12             = _mm256_sub_ps(iz1,jz2);
2089             dx13             = _mm256_sub_ps(ix1,jx3);
2090             dy13             = _mm256_sub_ps(iy1,jy3);
2091             dz13             = _mm256_sub_ps(iz1,jz3);
2092             dx21             = _mm256_sub_ps(ix2,jx1);
2093             dy21             = _mm256_sub_ps(iy2,jy1);
2094             dz21             = _mm256_sub_ps(iz2,jz1);
2095             dx22             = _mm256_sub_ps(ix2,jx2);
2096             dy22             = _mm256_sub_ps(iy2,jy2);
2097             dz22             = _mm256_sub_ps(iz2,jz2);
2098             dx23             = _mm256_sub_ps(ix2,jx3);
2099             dy23             = _mm256_sub_ps(iy2,jy3);
2100             dz23             = _mm256_sub_ps(iz2,jz3);
2101             dx31             = _mm256_sub_ps(ix3,jx1);
2102             dy31             = _mm256_sub_ps(iy3,jy1);
2103             dz31             = _mm256_sub_ps(iz3,jz1);
2104             dx32             = _mm256_sub_ps(ix3,jx2);
2105             dy32             = _mm256_sub_ps(iy3,jy2);
2106             dz32             = _mm256_sub_ps(iz3,jz2);
2107             dx33             = _mm256_sub_ps(ix3,jx3);
2108             dy33             = _mm256_sub_ps(iy3,jy3);
2109             dz33             = _mm256_sub_ps(iz3,jz3);
2110
2111             /* Calculate squared distance and things based on it */
2112             rsq00            = gmx_mm256_calc_rsq_ps(dx00,dy00,dz00);
2113             rsq11            = gmx_mm256_calc_rsq_ps(dx11,dy11,dz11);
2114             rsq12            = gmx_mm256_calc_rsq_ps(dx12,dy12,dz12);
2115             rsq13            = gmx_mm256_calc_rsq_ps(dx13,dy13,dz13);
2116             rsq21            = gmx_mm256_calc_rsq_ps(dx21,dy21,dz21);
2117             rsq22            = gmx_mm256_calc_rsq_ps(dx22,dy22,dz22);
2118             rsq23            = gmx_mm256_calc_rsq_ps(dx23,dy23,dz23);
2119             rsq31            = gmx_mm256_calc_rsq_ps(dx31,dy31,dz31);
2120             rsq32            = gmx_mm256_calc_rsq_ps(dx32,dy32,dz32);
2121             rsq33            = gmx_mm256_calc_rsq_ps(dx33,dy33,dz33);
2122
2123             rinv00           = gmx_mm256_invsqrt_ps(rsq00);
2124             rinv11           = gmx_mm256_invsqrt_ps(rsq11);
2125             rinv12           = gmx_mm256_invsqrt_ps(rsq12);
2126             rinv13           = gmx_mm256_invsqrt_ps(rsq13);
2127             rinv21           = gmx_mm256_invsqrt_ps(rsq21);
2128             rinv22           = gmx_mm256_invsqrt_ps(rsq22);
2129             rinv23           = gmx_mm256_invsqrt_ps(rsq23);
2130             rinv31           = gmx_mm256_invsqrt_ps(rsq31);
2131             rinv32           = gmx_mm256_invsqrt_ps(rsq32);
2132             rinv33           = gmx_mm256_invsqrt_ps(rsq33);
2133
2134             rinvsq11         = _mm256_mul_ps(rinv11,rinv11);
2135             rinvsq12         = _mm256_mul_ps(rinv12,rinv12);
2136             rinvsq13         = _mm256_mul_ps(rinv13,rinv13);
2137             rinvsq21         = _mm256_mul_ps(rinv21,rinv21);
2138             rinvsq22         = _mm256_mul_ps(rinv22,rinv22);
2139             rinvsq23         = _mm256_mul_ps(rinv23,rinv23);
2140             rinvsq31         = _mm256_mul_ps(rinv31,rinv31);
2141             rinvsq32         = _mm256_mul_ps(rinv32,rinv32);
2142             rinvsq33         = _mm256_mul_ps(rinv33,rinv33);
2143
2144             fjx0             = _mm256_setzero_ps();
2145             fjy0             = _mm256_setzero_ps();
2146             fjz0             = _mm256_setzero_ps();
2147             fjx1             = _mm256_setzero_ps();
2148             fjy1             = _mm256_setzero_ps();
2149             fjz1             = _mm256_setzero_ps();
2150             fjx2             = _mm256_setzero_ps();
2151             fjy2             = _mm256_setzero_ps();
2152             fjz2             = _mm256_setzero_ps();
2153             fjx3             = _mm256_setzero_ps();
2154             fjy3             = _mm256_setzero_ps();
2155             fjz3             = _mm256_setzero_ps();
2156
2157             /**************************
2158              * CALCULATE INTERACTIONS *
2159              **************************/
2160
2161             r00              = _mm256_mul_ps(rsq00,rinv00);
2162             r00              = _mm256_andnot_ps(dummy_mask,r00);
2163
2164             /* Calculate table index by multiplying r with table scale and truncate to integer */
2165             rt               = _mm256_mul_ps(r00,vftabscale);
2166             vfitab           = _mm256_cvttps_epi32(rt);
2167             vfeps            = _mm256_sub_ps(rt,_mm256_round_ps(rt, _MM_FROUND_FLOOR));
2168             /*         AVX1 does not support 256-bit integer operations, so now we go to 128-bit mode... */
2169             vfitab_lo        = _mm256_extractf128_si256(vfitab,0x0);
2170             vfitab_hi        = _mm256_extractf128_si256(vfitab,0x1);
2171             vfitab_lo        = _mm_slli_epi32(vfitab_lo,3);
2172             vfitab_hi        = _mm_slli_epi32(vfitab_hi,3);
2173
2174             /* CUBIC SPLINE TABLE DISPERSION */
2175             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
2176                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
2177             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
2178                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
2179             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
2180                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
2181             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
2182                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
2183             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
2184             Heps             = _mm256_mul_ps(vfeps,H);
2185             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
2186             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
2187             fvdw6            = _mm256_mul_ps(c6_00,FF);
2188
2189             /* CUBIC SPLINE TABLE REPULSION */
2190             vfitab_lo        = _mm_add_epi32(vfitab_lo,ifour);
2191             vfitab_hi        = _mm_add_epi32(vfitab_hi,ifour);
2192             Y                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,0)),
2193                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,0)));
2194             F                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,1)),
2195                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,1)));
2196             G                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,2)),
2197                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,2)));
2198             H                = gmx_mm256_set_m128(_mm_load_ps(vftab + _mm_extract_epi32(vfitab_hi,3)),
2199                                                   _mm_load_ps(vftab + _mm_extract_epi32(vfitab_lo,3)));
2200             GMX_MM256_HALFTRANSPOSE4_PS(Y,F,G,H);
2201             Heps             = _mm256_mul_ps(vfeps,H);
2202             Fp               = _mm256_add_ps(F,_mm256_mul_ps(vfeps,_mm256_add_ps(G,Heps)));
2203             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(vfeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
2204             fvdw12           = _mm256_mul_ps(c12_00,FF);
2205             fvdw             = _mm256_xor_ps(signbit,_mm256_mul_ps(_mm256_add_ps(fvdw6,fvdw12),_mm256_mul_ps(vftabscale,rinv00)));
2206
2207             fscal            = fvdw;
2208
2209             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
2210
2211             /* Calculate temporary vectorial force */
2212             tx               = _mm256_mul_ps(fscal,dx00);
2213             ty               = _mm256_mul_ps(fscal,dy00);
2214             tz               = _mm256_mul_ps(fscal,dz00);
2215
2216             /* Update vectorial force */
2217             fix0             = _mm256_add_ps(fix0,tx);
2218             fiy0             = _mm256_add_ps(fiy0,ty);
2219             fiz0             = _mm256_add_ps(fiz0,tz);
2220
2221             fjx0             = _mm256_add_ps(fjx0,tx);
2222             fjy0             = _mm256_add_ps(fjy0,ty);
2223             fjz0             = _mm256_add_ps(fjz0,tz);
2224
2225             /**************************
2226              * CALCULATE INTERACTIONS *
2227              **************************/
2228
2229             r11              = _mm256_mul_ps(rsq11,rinv11);
2230             r11              = _mm256_andnot_ps(dummy_mask,r11);
2231
2232             /* EWALD ELECTROSTATICS */
2233             
2234             /* Analytical PME correction */
2235             zeta2            = _mm256_mul_ps(beta2,rsq11);
2236             rinv3            = _mm256_mul_ps(rinvsq11,rinv11);
2237             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
2238             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
2239             felec            = _mm256_mul_ps(qq11,felec);
2240             
2241             fscal            = felec;
2242
2243             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
2244
2245             /* Calculate temporary vectorial force */
2246             tx               = _mm256_mul_ps(fscal,dx11);
2247             ty               = _mm256_mul_ps(fscal,dy11);
2248             tz               = _mm256_mul_ps(fscal,dz11);
2249
2250             /* Update vectorial force */
2251             fix1             = _mm256_add_ps(fix1,tx);
2252             fiy1             = _mm256_add_ps(fiy1,ty);
2253             fiz1             = _mm256_add_ps(fiz1,tz);
2254
2255             fjx1             = _mm256_add_ps(fjx1,tx);
2256             fjy1             = _mm256_add_ps(fjy1,ty);
2257             fjz1             = _mm256_add_ps(fjz1,tz);
2258
2259             /**************************
2260              * CALCULATE INTERACTIONS *
2261              **************************/
2262
2263             r12              = _mm256_mul_ps(rsq12,rinv12);
2264             r12              = _mm256_andnot_ps(dummy_mask,r12);
2265
2266             /* EWALD ELECTROSTATICS */
2267             
2268             /* Analytical PME correction */
2269             zeta2            = _mm256_mul_ps(beta2,rsq12);
2270             rinv3            = _mm256_mul_ps(rinvsq12,rinv12);
2271             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
2272             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
2273             felec            = _mm256_mul_ps(qq12,felec);
2274             
2275             fscal            = felec;
2276
2277             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
2278
2279             /* Calculate temporary vectorial force */
2280             tx               = _mm256_mul_ps(fscal,dx12);
2281             ty               = _mm256_mul_ps(fscal,dy12);
2282             tz               = _mm256_mul_ps(fscal,dz12);
2283
2284             /* Update vectorial force */
2285             fix1             = _mm256_add_ps(fix1,tx);
2286             fiy1             = _mm256_add_ps(fiy1,ty);
2287             fiz1             = _mm256_add_ps(fiz1,tz);
2288
2289             fjx2             = _mm256_add_ps(fjx2,tx);
2290             fjy2             = _mm256_add_ps(fjy2,ty);
2291             fjz2             = _mm256_add_ps(fjz2,tz);
2292
2293             /**************************
2294              * CALCULATE INTERACTIONS *
2295              **************************/
2296
2297             r13              = _mm256_mul_ps(rsq13,rinv13);
2298             r13              = _mm256_andnot_ps(dummy_mask,r13);
2299
2300             /* EWALD ELECTROSTATICS */
2301             
2302             /* Analytical PME correction */
2303             zeta2            = _mm256_mul_ps(beta2,rsq13);
2304             rinv3            = _mm256_mul_ps(rinvsq13,rinv13);
2305             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
2306             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
2307             felec            = _mm256_mul_ps(qq13,felec);
2308             
2309             fscal            = felec;
2310
2311             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
2312
2313             /* Calculate temporary vectorial force */
2314             tx               = _mm256_mul_ps(fscal,dx13);
2315             ty               = _mm256_mul_ps(fscal,dy13);
2316             tz               = _mm256_mul_ps(fscal,dz13);
2317
2318             /* Update vectorial force */
2319             fix1             = _mm256_add_ps(fix1,tx);
2320             fiy1             = _mm256_add_ps(fiy1,ty);
2321             fiz1             = _mm256_add_ps(fiz1,tz);
2322
2323             fjx3             = _mm256_add_ps(fjx3,tx);
2324             fjy3             = _mm256_add_ps(fjy3,ty);
2325             fjz3             = _mm256_add_ps(fjz3,tz);
2326
2327             /**************************
2328              * CALCULATE INTERACTIONS *
2329              **************************/
2330
2331             r21              = _mm256_mul_ps(rsq21,rinv21);
2332             r21              = _mm256_andnot_ps(dummy_mask,r21);
2333
2334             /* EWALD ELECTROSTATICS */
2335             
2336             /* Analytical PME correction */
2337             zeta2            = _mm256_mul_ps(beta2,rsq21);
2338             rinv3            = _mm256_mul_ps(rinvsq21,rinv21);
2339             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
2340             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
2341             felec            = _mm256_mul_ps(qq21,felec);
2342             
2343             fscal            = felec;
2344
2345             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
2346
2347             /* Calculate temporary vectorial force */
2348             tx               = _mm256_mul_ps(fscal,dx21);
2349             ty               = _mm256_mul_ps(fscal,dy21);
2350             tz               = _mm256_mul_ps(fscal,dz21);
2351
2352             /* Update vectorial force */
2353             fix2             = _mm256_add_ps(fix2,tx);
2354             fiy2             = _mm256_add_ps(fiy2,ty);
2355             fiz2             = _mm256_add_ps(fiz2,tz);
2356
2357             fjx1             = _mm256_add_ps(fjx1,tx);
2358             fjy1             = _mm256_add_ps(fjy1,ty);
2359             fjz1             = _mm256_add_ps(fjz1,tz);
2360
2361             /**************************
2362              * CALCULATE INTERACTIONS *
2363              **************************/
2364
2365             r22              = _mm256_mul_ps(rsq22,rinv22);
2366             r22              = _mm256_andnot_ps(dummy_mask,r22);
2367
2368             /* EWALD ELECTROSTATICS */
2369             
2370             /* Analytical PME correction */
2371             zeta2            = _mm256_mul_ps(beta2,rsq22);
2372             rinv3            = _mm256_mul_ps(rinvsq22,rinv22);
2373             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
2374             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
2375             felec            = _mm256_mul_ps(qq22,felec);
2376             
2377             fscal            = felec;
2378
2379             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
2380
2381             /* Calculate temporary vectorial force */
2382             tx               = _mm256_mul_ps(fscal,dx22);
2383             ty               = _mm256_mul_ps(fscal,dy22);
2384             tz               = _mm256_mul_ps(fscal,dz22);
2385
2386             /* Update vectorial force */
2387             fix2             = _mm256_add_ps(fix2,tx);
2388             fiy2             = _mm256_add_ps(fiy2,ty);
2389             fiz2             = _mm256_add_ps(fiz2,tz);
2390
2391             fjx2             = _mm256_add_ps(fjx2,tx);
2392             fjy2             = _mm256_add_ps(fjy2,ty);
2393             fjz2             = _mm256_add_ps(fjz2,tz);
2394
2395             /**************************
2396              * CALCULATE INTERACTIONS *
2397              **************************/
2398
2399             r23              = _mm256_mul_ps(rsq23,rinv23);
2400             r23              = _mm256_andnot_ps(dummy_mask,r23);
2401
2402             /* EWALD ELECTROSTATICS */
2403             
2404             /* Analytical PME correction */
2405             zeta2            = _mm256_mul_ps(beta2,rsq23);
2406             rinv3            = _mm256_mul_ps(rinvsq23,rinv23);
2407             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
2408             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
2409             felec            = _mm256_mul_ps(qq23,felec);
2410             
2411             fscal            = felec;
2412
2413             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
2414
2415             /* Calculate temporary vectorial force */
2416             tx               = _mm256_mul_ps(fscal,dx23);
2417             ty               = _mm256_mul_ps(fscal,dy23);
2418             tz               = _mm256_mul_ps(fscal,dz23);
2419
2420             /* Update vectorial force */
2421             fix2             = _mm256_add_ps(fix2,tx);
2422             fiy2             = _mm256_add_ps(fiy2,ty);
2423             fiz2             = _mm256_add_ps(fiz2,tz);
2424
2425             fjx3             = _mm256_add_ps(fjx3,tx);
2426             fjy3             = _mm256_add_ps(fjy3,ty);
2427             fjz3             = _mm256_add_ps(fjz3,tz);
2428
2429             /**************************
2430              * CALCULATE INTERACTIONS *
2431              **************************/
2432
2433             r31              = _mm256_mul_ps(rsq31,rinv31);
2434             r31              = _mm256_andnot_ps(dummy_mask,r31);
2435
2436             /* EWALD ELECTROSTATICS */
2437             
2438             /* Analytical PME correction */
2439             zeta2            = _mm256_mul_ps(beta2,rsq31);
2440             rinv3            = _mm256_mul_ps(rinvsq31,rinv31);
2441             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
2442             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
2443             felec            = _mm256_mul_ps(qq31,felec);
2444             
2445             fscal            = felec;
2446
2447             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
2448
2449             /* Calculate temporary vectorial force */
2450             tx               = _mm256_mul_ps(fscal,dx31);
2451             ty               = _mm256_mul_ps(fscal,dy31);
2452             tz               = _mm256_mul_ps(fscal,dz31);
2453
2454             /* Update vectorial force */
2455             fix3             = _mm256_add_ps(fix3,tx);
2456             fiy3             = _mm256_add_ps(fiy3,ty);
2457             fiz3             = _mm256_add_ps(fiz3,tz);
2458
2459             fjx1             = _mm256_add_ps(fjx1,tx);
2460             fjy1             = _mm256_add_ps(fjy1,ty);
2461             fjz1             = _mm256_add_ps(fjz1,tz);
2462
2463             /**************************
2464              * CALCULATE INTERACTIONS *
2465              **************************/
2466
2467             r32              = _mm256_mul_ps(rsq32,rinv32);
2468             r32              = _mm256_andnot_ps(dummy_mask,r32);
2469
2470             /* EWALD ELECTROSTATICS */
2471             
2472             /* Analytical PME correction */
2473             zeta2            = _mm256_mul_ps(beta2,rsq32);
2474             rinv3            = _mm256_mul_ps(rinvsq32,rinv32);
2475             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
2476             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
2477             felec            = _mm256_mul_ps(qq32,felec);
2478             
2479             fscal            = felec;
2480
2481             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
2482
2483             /* Calculate temporary vectorial force */
2484             tx               = _mm256_mul_ps(fscal,dx32);
2485             ty               = _mm256_mul_ps(fscal,dy32);
2486             tz               = _mm256_mul_ps(fscal,dz32);
2487
2488             /* Update vectorial force */
2489             fix3             = _mm256_add_ps(fix3,tx);
2490             fiy3             = _mm256_add_ps(fiy3,ty);
2491             fiz3             = _mm256_add_ps(fiz3,tz);
2492
2493             fjx2             = _mm256_add_ps(fjx2,tx);
2494             fjy2             = _mm256_add_ps(fjy2,ty);
2495             fjz2             = _mm256_add_ps(fjz2,tz);
2496
2497             /**************************
2498              * CALCULATE INTERACTIONS *
2499              **************************/
2500
2501             r33              = _mm256_mul_ps(rsq33,rinv33);
2502             r33              = _mm256_andnot_ps(dummy_mask,r33);
2503
2504             /* EWALD ELECTROSTATICS */
2505             
2506             /* Analytical PME correction */
2507             zeta2            = _mm256_mul_ps(beta2,rsq33);
2508             rinv3            = _mm256_mul_ps(rinvsq33,rinv33);
2509             pmecorrF         = gmx_mm256_pmecorrF_ps(zeta2);
2510             felec            = _mm256_add_ps( _mm256_mul_ps(pmecorrF,beta3), rinv3);
2511             felec            = _mm256_mul_ps(qq33,felec);
2512             
2513             fscal            = felec;
2514
2515             fscal            = _mm256_andnot_ps(dummy_mask,fscal);
2516
2517             /* Calculate temporary vectorial force */
2518             tx               = _mm256_mul_ps(fscal,dx33);
2519             ty               = _mm256_mul_ps(fscal,dy33);
2520             tz               = _mm256_mul_ps(fscal,dz33);
2521
2522             /* Update vectorial force */
2523             fix3             = _mm256_add_ps(fix3,tx);
2524             fiy3             = _mm256_add_ps(fiy3,ty);
2525             fiz3             = _mm256_add_ps(fiz3,tz);
2526
2527             fjx3             = _mm256_add_ps(fjx3,tx);
2528             fjy3             = _mm256_add_ps(fjy3,ty);
2529             fjz3             = _mm256_add_ps(fjz3,tz);
2530
2531             fjptrA             = (jnrlistA>=0) ? f+j_coord_offsetA : scratch;
2532             fjptrB             = (jnrlistB>=0) ? f+j_coord_offsetB : scratch;
2533             fjptrC             = (jnrlistC>=0) ? f+j_coord_offsetC : scratch;
2534             fjptrD             = (jnrlistD>=0) ? f+j_coord_offsetD : scratch;
2535             fjptrE             = (jnrlistE>=0) ? f+j_coord_offsetE : scratch;
2536             fjptrF             = (jnrlistF>=0) ? f+j_coord_offsetF : scratch;
2537             fjptrG             = (jnrlistG>=0) ? f+j_coord_offsetG : scratch;
2538             fjptrH             = (jnrlistH>=0) ? f+j_coord_offsetH : scratch;
2539
2540             gmx_mm256_decrement_4rvec_8ptr_swizzle_ps(fjptrA,fjptrB,fjptrC,fjptrD,fjptrE,fjptrF,fjptrG,fjptrH,
2541                                                       fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,
2542                                                       fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
2543
2544             /* Inner loop uses 565 flops */
2545         }
2546
2547         /* End of innermost loop */
2548
2549         gmx_mm256_update_iforce_4atom_swizzle_ps(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
2550                                                  f+i_coord_offset,fshift+i_shift_offset);
2551
2552         /* Increment number of inner iterations */
2553         inneriter                  += j_index_end - j_index_start;
2554
2555         /* Outer loop uses 24 flops */
2556     }
2557
2558     /* Increment number of outer iterations */
2559     outeriter        += nri;
2560
2561     /* Update outer/inner flops */
2562
2563     inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_F,outeriter*24 + inneriter*565);
2564 }