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