85c32b473eda4bc5bad8487613071b5307458832
[alexxy/gromacs.git] / src / gromacs / gmxlib / nonbonded / nb_generic_cg.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-2004, The GROMACS development team.
6  * Copyright (c) 2013,2014, by the GROMACS development team, led by
7  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8  * and including many others, as listed in the AUTHORS file in the
9  * top-level source 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 #include "gmxpre.h"
38
39 #include "config.h"
40
41 #include <math.h>
42
43 #include "gromacs/legacyheaders/types/simple.h"
44 #include "gromacs/math/vec.h"
45 #include "gromacs/legacyheaders/typedefs.h"
46 #include "nb_generic_cg.h"
47 #include "gromacs/legacyheaders/nonbonded.h"
48 #include "nb_kernel.h"
49 #include "gromacs/legacyheaders/nrnb.h"
50
51 #include "gromacs/utility/fatalerror.h"
52
53 void
54 gmx_nb_generic_cg_kernel(t_nblist *                nlist,
55                          rvec *                    xx,
56                          rvec *                    ff,
57                          t_forcerec *              fr,
58                          t_mdatoms *               mdatoms,
59                          nb_kernel_data_t *        kernel_data,
60                          t_nrnb *                  nrnb)
61 {
62     int           nri, ntype, table_nelements, ielec, ivdw;
63     real          facel, gbtabscale;
64     int           n, is3, i3, k, nj0, nj1, j3, ggid, nnn, n0;
65     int           ai0, ai1, ai, aj0, aj1, aj;
66     real          shX, shY, shZ;
67     real          fscal, tx, ty, tz;
68     real          rinvsq;
69     real          iq;
70     real          qq, vcoul, krsq, vctot;
71     int           nti, nvdwparam;
72     int           tj;
73     real          rt, r, eps, eps2, Y, F, Geps, Heps2, VV, FF, Fp, fijD, fijR;
74     real          rinvsix;
75     real          Vvdwtot;
76     real          Vvdw_rep, Vvdw_disp;
77     real          ix, iy, iz, fix, fiy, fiz;
78     real          jx, jy, jz;
79     real          dx, dy, dz, rsq, rinv;
80     real          c6, c12, cexp1, cexp2, br;
81     real *        charge;
82     real *        shiftvec;
83     real *        vdwparam;
84     int *         shift;
85     int *         type;
86     t_excl *      excl;
87     real *        fshift;
88     real *        Vc;
89     real *        Vvdw;
90     real          tabscale;
91     real *        VFtab;
92     real *        x;
93     real *        f;
94
95     x                   = xx[0];
96     f                   = ff[0];
97     ielec               = nlist->ielec;
98     ivdw                = nlist->ivdw;
99
100     fshift              = fr->fshift[0];
101     Vc                  = kernel_data->energygrp_elec;
102     Vvdw                = kernel_data->energygrp_vdw;
103     tabscale            = kernel_data->table_elec_vdw->scale;
104     VFtab               = kernel_data->table_elec_vdw->data;
105
106     /* avoid compiler warnings for cases that cannot happen */
107     nnn                 = 0;
108     vcoul               = 0.0;
109     eps                 = 0.0;
110     eps2                = 0.0;
111
112     /* 3 VdW parameters for buckingham, otherwise 2 */
113     nvdwparam           = (nlist->ivdw == 2) ? 3 : 2;
114     table_nelements     = (ielec == 3) ? 4 : 0;
115     table_nelements    += (ivdw == 3) ? 8 : 0;
116
117     charge              = mdatoms->chargeA;
118     type                = mdatoms->typeA;
119     facel               = fr->epsfac;
120     shiftvec            = fr->shift_vec[0];
121     vdwparam            = fr->nbfp;
122     ntype               = fr->ntype;
123
124     for (n = 0; (n < nlist->nri); n++)
125     {
126         is3              = 3*nlist->shift[n];
127         shX              = shiftvec[is3];
128         shY              = shiftvec[is3+1];
129         shZ              = shiftvec[is3+2];
130         nj0              = nlist->jindex[n];
131         nj1              = nlist->jindex[n+1];
132         ai0              = nlist->iinr[n];
133         ai1              = nlist->iinr_end[n];
134         vctot            = 0;
135         Vvdwtot          = 0;
136         fix              = 0;
137         fiy              = 0;
138         fiz              = 0;
139
140         for (k = nj0; (k < nj1); k++)
141         {
142             aj0              = nlist->jjnr[k];
143             aj1              = nlist->jjnr_end[k];
144             excl             = &nlist->excl[k*MAX_CGCGSIZE];
145
146             for (ai = ai0; (ai < ai1); ai++)
147             {
148                 i3               = ai*3;
149                 ix               = shX + x[i3+0];
150                 iy               = shY + x[i3+1];
151                 iz               = shZ + x[i3+2];
152                 iq               = facel*charge[ai];
153                 nti              = nvdwparam*ntype*type[ai];
154
155                 /* Note that this code currently calculates
156                  * all LJ and Coulomb interactions,
157                  * even if the LJ parameters or charges are zero.
158                  * If required, this can be optimized.
159                  */
160
161                 for (aj = aj0; (aj < aj1); aj++)
162                 {
163                     /* Check if this interaction is excluded */
164                     if (excl[aj-aj0] & (1<<(ai-ai0)))
165                     {
166                         continue;
167                     }
168
169                     j3               = aj*3;
170                     jx               = x[j3+0];
171                     jy               = x[j3+1];
172                     jz               = x[j3+2];
173                     dx               = ix - jx;
174                     dy               = iy - jy;
175                     dz               = iz - jz;
176                     rsq              = dx*dx+dy*dy+dz*dz;
177                     rinv             = gmx_invsqrt(rsq);
178                     rinvsq           = rinv*rinv;
179                     fscal            = 0;
180
181                     if (ielec == 3 || ivdw == 3)
182                     {
183                         r                = rsq*rinv;
184                         rt               = r*tabscale;
185                         n0               = rt;
186                         eps              = rt-n0;
187                         eps2             = eps*eps;
188                         nnn              = table_nelements*n0;
189                     }
190
191                     /* Coulomb interaction. ielec==0 means no interaction */
192                     if (ielec > 0)
193                     {
194                         qq               = iq*charge[aj];
195
196                         switch (ielec)
197                         {
198                             case 1:
199                                 /* Vanilla cutoff coulomb */
200                                 vcoul            = qq*rinv;
201                                 fscal            = vcoul*rinvsq;
202                                 break;
203
204                             case 2:
205                                 /* Reaction-field */
206                                 krsq             = fr->k_rf*rsq;
207                                 vcoul            = qq*(rinv+krsq-fr->c_rf);
208                                 fscal            = qq*(rinv-2.0*krsq)*rinvsq;
209                                 break;
210
211                             case 3:
212                                 /* Tabulated coulomb */
213                                 Y                = VFtab[nnn];
214                                 F                = VFtab[nnn+1];
215                                 Geps             = eps*VFtab[nnn+2];
216                                 Heps2            = eps2*VFtab[nnn+3];
217                                 nnn             += 4;
218                                 Fp               = F+Geps+Heps2;
219                                 VV               = Y+eps*Fp;
220                                 FF               = Fp+Geps+2.0*Heps2;
221                                 vcoul            = qq*VV;
222                                 fscal            = -qq*FF*tabscale*rinv;
223                                 break;
224
225                             case 4:
226                                 /* GB */
227                                 gmx_fatal(FARGS, "Death & horror! GB generic interaction not implemented.\n");
228                                 break;
229
230                             default:
231                                 gmx_fatal(FARGS, "Death & horror! No generic coulomb interaction for ielec=%d.\n", ielec);
232                                 break;
233                         }
234                         vctot            = vctot+vcoul;
235                     }  /* End of coulomb interactions */
236
237
238                     /* VdW interaction. ivdw==0 means no interaction */
239                     if (ivdw > 0)
240                     {
241                         tj               = nti+nvdwparam*type[aj];
242
243                         switch (ivdw)
244                         {
245                             case 1:
246                                 /* Vanilla Lennard-Jones cutoff */
247                                 c6               = vdwparam[tj];
248                                 c12              = vdwparam[tj+1];
249
250                                 rinvsix          = rinvsq*rinvsq*rinvsq;
251                                 Vvdw_disp        = c6*rinvsix;
252                                 Vvdw_rep         = c12*rinvsix*rinvsix;
253                                 fscal           += (12.0*Vvdw_rep-6.0*Vvdw_disp)*rinvsq;
254                                 Vvdwtot          = Vvdwtot+Vvdw_rep-Vvdw_disp;
255                                 break;
256
257                             case 2:
258                                 /* Buckingham */
259                                 c6               = vdwparam[tj];
260                                 cexp1            = vdwparam[tj+1];
261                                 cexp2            = vdwparam[tj+2];
262
263                                 rinvsix          = rinvsq*rinvsq*rinvsq;
264                                 Vvdw_disp        = c6*rinvsix;
265                                 br               = cexp2*rsq*rinv;
266                                 Vvdw_rep         = cexp1*exp(-br);
267                                 fscal           += (br*Vvdw_rep-6.0*Vvdw_disp)*rinvsq;
268                                 Vvdwtot          = Vvdwtot+Vvdw_rep-Vvdw_disp;
269                                 break;
270
271                             case 3:
272                                 /* Tabulated VdW */
273                                 c6               = vdwparam[tj];
274                                 c12              = vdwparam[tj+1];
275
276                                 Y                = VFtab[nnn];
277                                 F                = VFtab[nnn+1];
278                                 Geps             = eps*VFtab[nnn+2];
279                                 Heps2            = eps2*VFtab[nnn+3];
280                                 Fp               = F+Geps+Heps2;
281                                 VV               = Y+eps*Fp;
282                                 FF               = Fp+Geps+2.0*Heps2;
283                                 Vvdw_disp        = c6*VV;
284                                 fijD             = c6*FF;
285                                 nnn             += 4;
286                                 Y                = VFtab[nnn];
287                                 F                = VFtab[nnn+1];
288                                 Geps             = eps*VFtab[nnn+2];
289                                 Heps2            = eps2*VFtab[nnn+3];
290                                 Fp               = F+Geps+Heps2;
291                                 VV               = Y+eps*Fp;
292                                 FF               = Fp+Geps+2.0*Heps2;
293                                 Vvdw_rep         = c12*VV;
294                                 fijR             = c12*FF;
295                                 fscal           += -(fijD+fijR)*tabscale*rinv;
296                                 Vvdwtot          = Vvdwtot + Vvdw_disp + Vvdw_rep;
297                                 break;
298
299                             default:
300                                 gmx_fatal(FARGS, "Death & horror! No generic VdW interaction for ivdw=%d.\n", ivdw);
301                                 break;
302                         }
303                     }  /* end VdW interactions */
304
305
306                     tx               = fscal*dx;
307                     ty               = fscal*dy;
308                     tz               = fscal*dz;
309                     f[i3+0]         += tx;
310                     f[i3+1]         += ty;
311                     f[i3+2]         += tz;
312                     f[j3+0]         -= tx;
313                     f[j3+1]         -= ty;
314                     f[j3+2]         -= tz;
315                     fix             += tx;
316                     fiy             += ty;
317                     fiz             += tz;
318                 }
319             }
320         }
321
322         fshift[is3]     += fix;
323         fshift[is3+1]   += fiy;
324         fshift[is3+2]   += fiz;
325         ggid             = nlist->gid[n];
326         Vc[ggid]        += vctot;
327         Vvdw[ggid]      += Vvdwtot;
328     }
329     /* Estimate flops, average for generic cg kernel:
330      * 12  flops per outer iteration
331      * 100 flops per inner iteration
332      */
333     inc_nrnb(nrnb, eNR_NBKERNEL_GENERIC_CG, nlist->nri*12 + nlist->jindex[n]*100);
334 }