2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2012,2013,2014,2015,2016, 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.
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.
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.
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.
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.
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.
37 #include "nbnxn_kernel_ref.h"
47 #include "gromacs/math/functions.h"
48 #include "gromacs/math/vec.h"
49 #include "gromacs/mdlib/force.h"
50 #include "gromacs/mdlib/gmx_omp_nthreads.h"
51 #include "gromacs/mdlib/nb_verlet.h"
52 #include "gromacs/mdlib/nbnxn_consts.h"
53 #include "gromacs/mdlib/nbnxn_kernels/nbnxn_kernel_common.h"
54 #include "gromacs/mdtypes/md_enums.h"
55 #include "gromacs/pbcutil/ishift.h"
56 #include "gromacs/utility/fatalerror.h"
57 #include "gromacs/utility/smalloc.h"
59 /*! \brief Typedefs for declaring lookup tables of kernel functions.
62 typedef void (*p_nbk_func_noener
)(const nbnxn_pairlist_t
*nbl
,
63 const nbnxn_atomdata_t
*nbat
,
64 const interaction_const_t
*ic
,
69 typedef void (*p_nbk_func_ener
)(const nbnxn_pairlist_t
*nbl
,
70 const nbnxn_atomdata_t
*nbat
,
71 const interaction_const_t
*ic
,
78 /* Analytical reaction-field kernels */
81 #include "gromacs/mdlib/nbnxn_kernels/nbnxn_kernel_ref_includes.h"
83 #define LJ_FORCE_SWITCH
84 #include "gromacs/mdlib/nbnxn_kernels/nbnxn_kernel_ref_includes.h"
85 #undef LJ_FORCE_SWITCH
87 #include "gromacs/mdlib/nbnxn_kernels/nbnxn_kernel_ref_includes.h"
91 #define LJ_EWALD_COMB_GEOM
92 #include "gromacs/mdlib/nbnxn_kernels/nbnxn_kernel_ref_includes.h"
93 #undef LJ_EWALD_COMB_GEOM
94 #define LJ_EWALD_COMB_LB
95 #include "gromacs/mdlib/nbnxn_kernels/nbnxn_kernel_ref_includes.h"
96 #undef LJ_EWALD_COMB_LB
102 /* Tabulated exclusion interaction electrostatics kernels */
103 #define CALC_COUL_TAB
105 #include "gromacs/mdlib/nbnxn_kernels/nbnxn_kernel_ref_includes.h"
107 #define LJ_FORCE_SWITCH
108 #include "gromacs/mdlib/nbnxn_kernels/nbnxn_kernel_ref_includes.h"
109 #undef LJ_FORCE_SWITCH
110 #define LJ_POT_SWITCH
111 #include "gromacs/mdlib/nbnxn_kernels/nbnxn_kernel_ref_includes.h"
115 #define LJ_EWALD_COMB_GEOM
116 #include "gromacs/mdlib/nbnxn_kernels/nbnxn_kernel_ref_includes.h"
117 #undef LJ_EWALD_COMB_GEOM
118 #define LJ_EWALD_COMB_LB
119 #include "gromacs/mdlib/nbnxn_kernels/nbnxn_kernel_ref_includes.h"
120 #undef LJ_EWALD_COMB_LB
123 /* Twin-range cut-off kernels */
124 #define VDW_CUTOFF_CHECK
126 #include "gromacs/mdlib/nbnxn_kernels/nbnxn_kernel_ref_includes.h"
128 #define LJ_FORCE_SWITCH
129 #include "gromacs/mdlib/nbnxn_kernels/nbnxn_kernel_ref_includes.h"
130 #undef LJ_FORCE_SWITCH
131 #define LJ_POT_SWITCH
132 #include "gromacs/mdlib/nbnxn_kernels/nbnxn_kernel_ref_includes.h"
136 #define LJ_EWALD_COMB_GEOM
137 #include "gromacs/mdlib/nbnxn_kernels/nbnxn_kernel_ref_includes.h"
138 #undef LJ_EWALD_COMB_GEOM
139 #define LJ_EWALD_COMB_LB
140 #include "gromacs/mdlib/nbnxn_kernels/nbnxn_kernel_ref_includes.h"
141 #undef LJ_EWALD_COMB_LB
144 #undef VDW_CUTOFF_CHECK
149 coultRF
, coultTAB
, coultTAB_TWIN
, coultNR
153 vdwtCUT
, vdwtFSWITCH
, vdwtPSWITCH
, vdwtEWALDGEOM
, vdwtEWALDLB
, vdwtNR
156 p_nbk_func_noener p_nbk_c_noener
[coultNR
][vdwtNR
] =
158 { nbnxn_kernel_ElecRF_VdwLJ_F_ref
, nbnxn_kernel_ElecRF_VdwLJFsw_F_ref
, nbnxn_kernel_ElecRF_VdwLJPsw_F_ref
, nbnxn_kernel_ElecRF_VdwLJEwCombGeom_F_ref
, nbnxn_kernel_ElecRF_VdwLJEwCombLB_F_ref
},
159 { nbnxn_kernel_ElecQSTab_VdwLJ_F_ref
, nbnxn_kernel_ElecQSTab_VdwLJFsw_F_ref
, nbnxn_kernel_ElecQSTab_VdwLJPsw_F_ref
, nbnxn_kernel_ElecQSTab_VdwLJEwCombGeom_F_ref
, nbnxn_kernel_ElecQSTab_VdwLJEwCombLB_F_ref
},
160 { nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_ref
, nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_F_ref
, nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_F_ref
, nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F_ref
, nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombLB_F_ref
}
163 p_nbk_func_ener p_nbk_c_ener
[coultNR
][vdwtNR
] =
165 { nbnxn_kernel_ElecRF_VdwLJ_VF_ref
, nbnxn_kernel_ElecRF_VdwLJFsw_VF_ref
, nbnxn_kernel_ElecRF_VdwLJPsw_VF_ref
, nbnxn_kernel_ElecRF_VdwLJEwCombGeom_VF_ref
, nbnxn_kernel_ElecRF_VdwLJEwCombLB_VF_ref
},
166 { nbnxn_kernel_ElecQSTab_VdwLJ_VF_ref
, nbnxn_kernel_ElecQSTab_VdwLJFsw_VF_ref
, nbnxn_kernel_ElecQSTab_VdwLJPsw_VF_ref
, nbnxn_kernel_ElecQSTab_VdwLJEwCombGeom_VF_ref
, nbnxn_kernel_ElecQSTab_VdwLJEwCombLB_VF_ref
},
167 { nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref
, nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_VF_ref
, nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_VF_ref
, nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF_ref
, nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombLB_VF_ref
}
170 p_nbk_func_ener p_nbk_c_energrp
[coultNR
][vdwtNR
] =
172 { nbnxn_kernel_ElecRF_VdwLJ_VgrpF_ref
, nbnxn_kernel_ElecRF_VdwLJFsw_VgrpF_ref
, nbnxn_kernel_ElecRF_VdwLJPsw_VgrpF_ref
, nbnxn_kernel_ElecRF_VdwLJEwCombGeom_VgrpF_ref
, nbnxn_kernel_ElecRF_VdwLJEwCombLB_VgrpF_ref
},
173 { nbnxn_kernel_ElecQSTab_VdwLJ_VgrpF_ref
, nbnxn_kernel_ElecQSTab_VdwLJFsw_VgrpF_ref
, nbnxn_kernel_ElecQSTab_VdwLJPsw_VgrpF_ref
, nbnxn_kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF_ref
, nbnxn_kernel_ElecQSTab_VdwLJEwCombLB_VgrpF_ref
},
174 { nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref
, nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_VgrpF_ref
, nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_VgrpF_ref
, nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF_ref
, nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombLB_VgrpF_ref
}
178 nbnxn_kernel_ref(const nbnxn_pairlist_set_t
*nbl_list
,
179 const nbnxn_atomdata_t
*nbat
,
180 const interaction_const_t
*ic
,
189 nbnxn_pairlist_t
**nbl
;
193 int nthreads gmx_unused
;
195 nnbl
= nbl_list
->nnbl
;
198 if (EEL_RF(ic
->eeltype
) || ic
->eeltype
== eelCUT
)
204 if (ic
->rcoulomb
== ic
->rvdw
)
210 coult
= coultTAB_TWIN
;
214 if (ic
->vdwtype
== evdwCUT
)
216 switch (ic
->vdw_modifier
)
218 case eintmodPOTSHIFT
:
222 case eintmodFORCESWITCH
:
225 case eintmodPOTSWITCH
:
229 gmx_incons("Unsupported VdW modifier");
233 else if (ic
->vdwtype
== evdwPME
)
235 if (ic
->ljpme_comb_rule
== ljcrGEOM
)
237 assert(nbat
->comb_rule
== ljcrGEOM
);
238 vdwt
= vdwtEWALDGEOM
;
242 assert(nbat
->comb_rule
== ljcrLB
);
248 gmx_incons("Unsupported vdwtype in nbnxn reference kernel");
251 // cppcheck-suppress unreadVariable
252 nthreads
= gmx_omp_nthreads_get(emntNonbonded
);
253 #pragma omp parallel for schedule(static) num_threads(nthreads)
254 for (nb
= 0; nb
< nnbl
; nb
++)
256 // Presently, the kernels do not call C++ code that can throw, so
257 // no need for a try/catch pair in this OpenMP region.
258 nbnxn_atomdata_output_t
*out
;
261 out
= &nbat
->out
[nb
];
263 if (clearF
== enbvClearFYes
)
265 clear_f(nbat
, nb
, out
->f
);
268 if ((force_flags
& GMX_FORCE_VIRIAL
) && nnbl
== 1)
274 fshift_p
= out
->fshift
;
276 if (clearF
== enbvClearFYes
)
278 clear_fshift(fshift_p
);
282 if (!(force_flags
& GMX_FORCE_ENERGY
))
284 /* Don't calculate energies */
285 p_nbk_c_noener
[coult
][vdwt
](nbl
[nb
], nbat
,
291 else if (out
->nV
== 1)
293 /* No energy groups */
297 p_nbk_c_ener
[coult
][vdwt
](nbl
[nb
], nbat
,
307 /* Calculate energy group contributions */
310 for (i
= 0; i
< out
->nV
; i
++)
314 for (i
= 0; i
< out
->nV
; i
++)
319 p_nbk_c_energrp
[coult
][vdwt
](nbl
[nb
], nbat
,
329 if (force_flags
& GMX_FORCE_ENERGY
)
331 reduce_energies_over_lists(nbat
, nnbl
, Vvdw
, Vc
);