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