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