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