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