9e93ed7bbfbee5125098235d11ce619023346762
[alexxy/gromacs.git] / src / mdlib / nbnxn_kernels / nbnxn_kernel_ref.c
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
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.
10  *
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.
15  *
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.
20  *
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.
25  *
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.
33  *
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.
36  */
37 #ifdef HAVE_CONFIG_H
38 #include <config.h>
39 #endif
40
41 #include <math.h>
42
43 #include "typedefs.h"
44 #include "vec.h"
45 #include "smalloc.h"
46 #include "force.h"
47 #include "gmx_omp_nthreads.h"
48 #include "nbnxn_kernel_ref.h"
49 #include "../nbnxn_consts.h"
50 #include "nbnxn_kernel_common.h"
51
52 /* Analytical reaction-field kernels */
53 #define CALC_COUL_RF
54
55 /* Include the force+energy kernels */
56 #define CALC_ENERGIES
57 #include "nbnxn_kernel_ref_outer.h"
58 #undef CALC_ENERGIES
59
60 /* Include the force+energygroups kernels */
61 #define CALC_ENERGIES
62 #define ENERGY_GROUPS
63 #include "nbnxn_kernel_ref_outer.h"
64 #undef ENERGY_GROUPS
65 #undef CALC_ENERGIES
66
67 /* Include the force only kernels */
68 #include "nbnxn_kernel_ref_outer.h"
69
70 #undef CALC_COUL_RF
71
72
73 /* Tabulated exclusion interaction electrostatics kernels */
74 #define CALC_COUL_TAB
75
76 /* Include the force+energy kernels */
77 #define CALC_ENERGIES
78 #include "nbnxn_kernel_ref_outer.h"
79 #undef CALC_ENERGIES
80
81 /* Include the force+energygroups kernels */
82 #define CALC_ENERGIES
83 #define ENERGY_GROUPS
84 #include "nbnxn_kernel_ref_outer.h"
85 #undef ENERGY_GROUPS
86 #undef CALC_ENERGIES
87
88 /* Include the force only kernels */
89 #include "nbnxn_kernel_ref_outer.h"
90
91 /* Twin-range cut-off kernels */
92 #define VDW_CUTOFF_CHECK
93
94 /* Include the force+energy kernels */
95 #define CALC_ENERGIES
96 #include "nbnxn_kernel_ref_outer.h"
97 #undef CALC_ENERGIES
98
99 /* Include the force+energygroups kernels */
100 #define CALC_ENERGIES
101 #define ENERGY_GROUPS
102 #include "nbnxn_kernel_ref_outer.h"
103 #undef ENERGY_GROUPS
104 #undef CALC_ENERGIES
105
106 /* Include the force only kernels */
107 #include "nbnxn_kernel_ref_outer.h"
108
109 #undef VDW_CUTOFF_CHECK
110
111 #undef CALC_COUL_TAB
112
113
114 typedef void (*p_nbk_func_ener)(const nbnxn_pairlist_t     *nbl,
115                                 const nbnxn_atomdata_t     *nbat,
116                                 const interaction_const_t  *ic,
117                                 rvec                       *shift_vec,
118                                 real                       *f,
119                                 real                       *fshift,
120                                 real                       *Vvdw,
121                                 real                       *Vc);
122
123 typedef void (*p_nbk_func_noener)(const nbnxn_pairlist_t     *nbl,
124                                   const nbnxn_atomdata_t     *nbat,
125                                   const interaction_const_t  *ic,
126                                   rvec                       *shift_vec,
127                                   real                       *f,
128                                   real                       *fshift);
129
130 enum { coultRF, coultTAB, coultTAB_TWIN, coultNR };
131
132 p_nbk_func_ener p_nbk_c_ener[coultNR] =
133 { nbnxn_kernel_ref_rf_ener,
134   nbnxn_kernel_ref_tab_ener,
135   nbnxn_kernel_ref_tab_twin_ener };
136
137 p_nbk_func_ener p_nbk_c_energrp[coultNR] =
138 { nbnxn_kernel_ref_rf_energrp,
139   nbnxn_kernel_ref_tab_energrp,
140   nbnxn_kernel_ref_tab_twin_energrp};
141
142 p_nbk_func_noener p_nbk_c_noener[coultNR] =
143 { nbnxn_kernel_ref_rf_noener,
144   nbnxn_kernel_ref_tab_noener,
145   nbnxn_kernel_ref_tab_twin_noener };
146
147 void
148 nbnxn_kernel_ref(const nbnxn_pairlist_set_t *nbl_list,
149                  const nbnxn_atomdata_t     *nbat,
150                  const interaction_const_t  *ic,
151                  rvec                       *shift_vec,
152                  int                        force_flags,
153                  int                        clearF,
154                  real                       *fshift,
155                  real                       *Vc,
156                  real                       *Vvdw)
157 {
158     int              nnbl;
159     nbnxn_pairlist_t **nbl;
160     int coult;
161     int nb;
162
163     nnbl = nbl_list->nnbl;
164     nbl  = nbl_list->nbl;
165
166     if (EEL_RF(ic->eeltype) || ic->eeltype == eelCUT)
167     {
168         coult = coultRF;
169     }
170     else
171     {
172         if (ic->rcoulomb == ic->rvdw)
173         {
174             coult = coultTAB;
175         }
176         else
177         {
178             coult = coultTAB_TWIN;
179         }
180     }
181
182 #pragma omp parallel for schedule(static) num_threads(gmx_omp_nthreads_get(emntNonbonded))
183     for(nb=0; nb<nnbl; nb++)
184     {
185         nbnxn_atomdata_output_t *out;
186         real *fshift_p;
187
188         out = &nbat->out[nb];
189
190         if (clearF == enbvClearFYes)
191         {
192             clear_f(nbat,nb,out->f);
193         }
194
195         if ((force_flags & GMX_FORCE_VIRIAL) && nnbl == 1)
196         {
197             fshift_p = fshift;
198         }
199         else
200         {
201             fshift_p = out->fshift;
202
203             if (clearF == enbvClearFYes)
204             {
205                 clear_fshift(fshift_p);
206             }
207         }
208
209         if (!(force_flags & GMX_FORCE_ENERGY))
210         {
211             /* Don't calculate energies */
212             p_nbk_c_noener[coult](nbl[nb],nbat,
213                                   ic,
214                                   shift_vec,
215                                   out->f,
216                                   fshift_p);
217         }
218         else if (out->nV == 1)
219         {
220             /* No energy groups */
221             out->Vvdw[0] = 0;
222             out->Vc[0]   = 0;
223
224             p_nbk_c_ener[coult](nbl[nb],nbat,
225                                 ic,
226                                 shift_vec,
227                                 out->f,
228                                 fshift_p,
229                                 out->Vvdw,
230                                 out->Vc);
231         }
232         else
233         {
234             /* Calculate energy group contributions */
235             int i;
236
237             for(i=0; i<out->nV; i++)
238             {
239                 out->Vvdw[i] = 0;
240             }
241             for(i=0; i<out->nV; i++)
242             {
243                 out->Vc[i] = 0;
244             }
245
246             p_nbk_c_energrp[coult](nbl[nb],nbat,
247                                    ic,
248                                    shift_vec,
249                                    out->f,
250                                    fshift_p,
251                                    out->Vvdw,
252                                    out->Vc);
253         }
254     }
255
256     if (force_flags & GMX_FORCE_ENERGY)
257     {
258         reduce_energies_over_lists(nbat,nnbl,Vvdw,Vc);
259     }
260 }