2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2009, The GROMACS Development Team
6 * Copyright (c) 2012, by the GROMACS development team, led by
7 * David van der Spoel, Berk Hess, Erik Lindahl, and including many
8 * others, as listed in the AUTHORS file in the top-level source
9 * directory and at http://www.gromacs.org.
11 * GROMACS is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 2.1
14 * of the License, or (at your option) any later version.
16 * GROMACS is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with GROMACS; if not, see
23 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 * If you want to redistribute modifications to GROMACS, please
27 * consider that scientific software is very special. Version
28 * control is crucial - bugs must be traceable. We will be happy to
29 * consider code for inclusion in the official distribution, but
30 * derived work must not be called official GROMACS. Details are found
31 * in the README & COPYING files - if they are missing, get the
32 * official version at http://www.gromacs.org.
34 * To help us fund GROMACS development, we humbly ask that you cite
35 * the research papers on the package. Check out http://www.gromacs.org.
38 #define UNROLLI NBNXN_CPU_CLUSTER_I_SIZE
39 #define UNROLLJ NBNXN_CPU_CLUSTER_I_SIZE
41 /* We could use nbat->xstride and nbat->fstride, but macros might be faster */
44 /* Local i-atom buffer strides */
49 /* All functionality defines are set here, except for:
50 * CALC_ENERGIES, ENERGY_GROUPS which are defined before.
51 * CHECK_EXCLS, which is set just before including the inner loop contents.
54 /* We always calculate shift forces, because it's cheap anyhow */
55 #define CALC_SHIFTFORCES
58 #define NBK_FUNC_NAME(x,y) x##_rf_##y
61 #ifndef VDW_CUTOFF_CHECK
62 #define NBK_FUNC_NAME(x,y) x##_tab_##y
64 #define NBK_FUNC_NAME(x,y) x##_tab_twin_##y
70 NBK_FUNC_NAME(nbnxn_kernel_ref,noener)
73 NBK_FUNC_NAME(nbnxn_kernel_ref,ener)
75 NBK_FUNC_NAME(nbnxn_kernel_ref,energrp)
79 (const nbnxn_pairlist_t *nbl,
80 const nbnxn_atomdata_t *nbat,
81 const interaction_const_t *ic,
84 #ifdef CALC_SHIFTFORCES
95 const nbnxn_ci_t *nbln;
96 const nbnxn_cj_t *l_cj;
103 #ifdef VDW_CUTOFF_CHECK
111 gmx_bool half_LJ,do_coul;
112 int cjind0,cjind1,cjind;
115 real xi[UNROLLI*XI_STRIDE];
116 real fi[UNROLLI*FI_STRIDE];
120 #ifndef ENERGY_GROUPS
125 int egp_sh_i[UNROLLI];
142 const real *tab_coul_FDV0;
144 const real *tab_coul_F;
145 const real *tab_coul_V;
156 sh_invrc6 = ic->sh_invrc6;
167 tabscale = ic->tabq_scale;
169 halfsp = 0.5/ic->tabq_scale;
173 tab_coul_FDV0 = ic->tabq_coul_FDV0;
175 tab_coul_F = ic->tabq_coul_F;
176 tab_coul_V = ic->tabq_coul_V;
181 egp_mask = (1<<nbat->neg_2log) - 1;
185 rcut2 = ic->rcoulomb*ic->rcoulomb;
186 #ifdef VDW_CUTOFF_CHECK
187 rvdw2 = ic->rvdw*ic->rvdw;
190 ntype2 = nbat->ntype*2;
195 shiftvec = shift_vec[0];
201 for(n=0; n<nbl->nci; n++)
207 ish = (nbln->shift & NBNXN_CI_SHIFT);
208 /* x, f and fshift are assumed to be stored with stride 3 */
210 cjind0 = nbln->cj_ind_start;
211 cjind1 = nbln->cj_ind_end;
212 /* Currently only works super-cells equal to sub-cells */
214 ci_sh = (ish == CENTRAL ? ci : -1);
216 half_LJ = (nbln->shift & NBNXN_CI_HALF_LJ(0));
217 do_coul = (nbln->shift & NBNXN_CI_DO_COUL(0));
220 #ifndef ENERGY_GROUPS
224 for(i=0; i<UNROLLI; i++)
226 egp_sh_i[i] = ((nbat->energrp[ci]>>(i*nbat->neg_2log)) & egp_mask)*nbat->nenergrp;
231 for(i=0; i<UNROLLI; i++)
235 xi[i*XI_STRIDE+d] = x[(ci*UNROLLI+i)*X_STRIDE+d] + shiftvec[ishf+d];
236 fi[i*FI_STRIDE+d] = 0;
240 /* With half_LJ we currently always calculate Coulomb interactions */
241 if (do_coul || half_LJ)
247 Vc_sub_self = 0.5*c_rf;
251 Vc_sub_self = 0.5*tab_coul_V[0];
253 Vc_sub_self = 0.5*tab_coul_FDV0[2];
258 for(i=0; i<UNROLLI; i++)
260 qi[i] = facel*q[ci*UNROLLI+i];
263 if (l_cj[nbln->cj_ind_start].cj == ci_sh)
266 Vc[egp_sh_i[i]+((nbat->energrp[ci]>>(i*nbat->neg_2log)) & egp_mask)]
270 -= qi[i]*q[ci*UNROLLI+i]*Vc_sub_self;
277 while (cjind < cjind1 && nbl->cj[cjind].excl != 0xffff)
284 #include "nbnxn_kernel_ref_inner.h"
288 /* cppcheck-suppress duplicateBranch */
292 #include "nbnxn_kernel_ref_inner.h"
297 #include "nbnxn_kernel_ref_inner.h"
303 for(; (cjind<cjind1); cjind++)
309 #include "nbnxn_kernel_ref_inner.h"
313 /* cppcheck-suppress duplicateBranch */
317 #include "nbnxn_kernel_ref_inner.h"
322 #include "nbnxn_kernel_ref_inner.h"
325 ninner += cjind1 - cjind0;
327 /* Add accumulated i-forces to the force array */
328 for(i=0; i<UNROLLI; i++)
332 f[(ci*UNROLLI+i)*F_STRIDE+d] += fi[i*FI_STRIDE+d];
335 #ifdef CALC_SHIFTFORCES
338 /* Add i forces to shifted force list */
339 for(i=0; i<UNROLLI; i++)
343 fshift[ishf+d] += fi[i*FI_STRIDE+d];
350 #ifndef ENERGY_GROUPS
358 printf("atom pairs %d\n",npair);
362 #undef CALC_SHIFTFORCES