Fixing copyright issues and code contributors
[alexxy/gromacs.git] / src / 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  * check out http://www.gromacs.org for more information.
7  * Copyright (c) 2012,2013, by the GROMACS development team, led by
8  * David van der Spoel, Berk Hess, Erik Lindahl, and including many
9  * others, as listed in the AUTHORS file in the top-level source
10  * directory and at http://www.gromacs.org.
11  *
12  * GROMACS is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public License
14  * as published by the Free Software Foundation; either version 2.1
15  * of the License, or (at your option) any later version.
16  *
17  * GROMACS is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Lesser General Public License for more details.
21  *
22  * You should have received a copy of the GNU Lesser General Public
23  * License along with GROMACS; if not, see
24  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
26  *
27  * If you want to redistribute modifications to GROMACS, please
28  * consider that scientific software is very special. Version
29  * control is crucial - bugs must be traceable. We will be happy to
30  * consider code for inclusion in the official distribution, but
31  * derived work must not be called official GROMACS. Details are found
32  * in the README & COPYING files - if they are missing, get the
33  * official version at http://www.gromacs.org.
34  *
35  * To help us fund GROMACS development, we humbly ask that you cite
36  * the research papers on the package. Check out http://www.gromacs.org.
37  */
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif
41
42 #include <math.h>
43
44 #include "types/simple.h"
45 #include "vec.h"
46 #include "typedefs.h"
47 #include "nb_generic_cg.h"
48 #include "nonbonded.h"
49 #include "nb_kernel.h"
50 #include "nrnb.h"
51
52  void
53 gmx_nb_generic_cg_kernel(t_nblist *                nlist,
54                          rvec *                    xx,
55                          rvec *                    ff,
56                          t_forcerec *              fr,
57                          t_mdatoms *               mdatoms,
58                          nb_kernel_data_t *        kernel_data,
59                          t_nrnb *                  nrnb)
60 {
61      int           nri,ntype,table_nelements,ielec,ivdw;
62      real          facel,gbtabscale;
63      int           n,is3,i3,k,nj0,nj1,j3,ggid,nnn,n0;
64      int           ai0,ai1,ai,aj0,aj1,aj;
65      real          shX,shY,shZ;
66      real          fscal,tx,ty,tz;
67      real          rinvsq;
68      real          iq;
69      real          qq,vcoul,krsq,vctot;
70      int           nti,nvdwparam;
71      int           tj;
72      real          rt,r,eps,eps2,Y,F,Geps,Heps2,VV,FF,Fp,fijD,fijR;
73      real          rinvsix;
74      real          Vvdwtot;
75      real          Vvdw_rep,Vvdw_disp;
76      real          ix,iy,iz,fix,fiy,fiz;
77      real          jx,jy,jz;
78      real          dx,dy,dz,rsq,rinv;
79      real          c6,c12,cexp1,cexp2,br;
80      real *        charge;
81      real *        shiftvec;
82      real *        vdwparam;
83      int *         shift;
84      int *         type;
85      t_excl *      excl;
86      real *        fshift;
87      real *        Vc;
88      real *        Vvdw;
89      real          tabscale;
90      real *        VFtab;
91      real *        x;
92      real *        f;
93
94      x                   = xx[0];
95      f                   = ff[0];
96      ielec               = nlist->ielec;
97      ivdw                = nlist->ivdw;
98
99      fshift              = fr->fshift[0];
100      Vc                  = kernel_data->energygrp_elec;
101      Vvdw                = kernel_data->energygrp_vdw;
102      tabscale            = kernel_data->table_elec_vdw->scale;
103      VFtab               = kernel_data->table_elec_vdw->data;
104
105      /* avoid compiler warnings for cases that cannot happen */
106      nnn                 = 0;
107      vcoul               = 0.0;
108      eps                 = 0.0;
109      eps2                = 0.0;
110      
111      /* 3 VdW parameters for buckingham, otherwise 2 */
112      nvdwparam           = (nlist->ivdw==2) ? 3 : 2;
113      table_nelements     = (ielec==3) ? 4 : 0;
114      table_nelements    += (ivdw==3) ? 8 : 0;
115      
116      charge              = mdatoms->chargeA;
117      type                = mdatoms->typeA;
118      facel               = fr->epsfac;
119      shiftvec            = fr->shift_vec[0];
120      vdwparam            = fr->nbfp;
121      ntype               = fr->ntype;
122      
123      for(n=0; (n<nlist->nri); n++)
124      {
125          is3              = 3*nlist->shift[n];     
126          shX              = shiftvec[is3];  
127          shY              = shiftvec[is3+1];
128          shZ              = shiftvec[is3+2];
129          nj0              = nlist->jindex[n];      
130          nj1              = nlist->jindex[n+1];    
131          ai0              = nlist->iinr[n];
132          ai1              = nlist->iinr_end[n];
133          vctot            = 0;              
134          Vvdwtot          = 0;              
135          fix              = 0;
136          fiy              = 0;
137          fiz              = 0;
138          
139          for(k=nj0; (k<nj1); k++)
140          {
141              aj0              = nlist->jjnr[k];
142              aj1              = nlist->jjnr_end[k];
143              excl             = &nlist->excl[k*MAX_CGCGSIZE];
144
145              for(ai=ai0; (ai<ai1); ai++)
146              {
147                  i3               = ai*3;
148                  ix               = shX + x[i3+0];
149                  iy               = shY + x[i3+1];
150                  iz               = shZ + x[i3+2];
151                  iq               = facel*charge[ai];
152                  nti              = nvdwparam*ntype*type[ai];
153
154                  /* Note that this code currently calculates
155                   * all LJ and Coulomb interactions,
156                   * even if the LJ parameters or charges are zero.
157                   * If required, this can be optimized.
158                   */
159
160                  for(aj=aj0; (aj<aj1); aj++)
161                  {
162                      /* Check if this interaction is excluded */
163                      if (excl[aj-aj0] & (1<<(ai-ai0)))
164                      {
165                          continue;
166                      }
167
168                      j3               = aj*3;
169                      jx               = x[j3+0];
170                      jy               = x[j3+1];
171                      jz               = x[j3+2];
172                      dx               = ix - jx;      
173                      dy               = iy - jy;      
174                      dz               = iz - jz;      
175                      rsq              = dx*dx+dy*dy+dz*dz;
176                      rinv             = gmx_invsqrt(rsq);
177                      rinvsq           = rinv*rinv;  
178                      fscal            = 0;
179
180                      if (ielec==3 || ivdw==3)
181                      {
182                          r                = rsq*rinv;
183                          rt               = r*tabscale;     
184                          n0               = rt;             
185                          eps              = rt-n0;          
186                          eps2             = eps*eps;        
187                          nnn              = table_nelements*n0;                                         
188                      }
189                      
190                      /* Coulomb interaction. ielec==0 means no interaction */
191                      if (ielec > 0)
192                      {
193                          qq               = iq*charge[aj]; 
194                          
195                          switch(ielec)
196                          {
197                          case 1:
198                              /* Vanilla cutoff coulomb */
199                              vcoul            = qq*rinv;      
200                              fscal            = vcoul*rinvsq; 
201                              break;
202                              
203                          case 2:
204                              /* Reaction-field */
205                              krsq             = fr->k_rf*rsq;      
206                              vcoul            = qq*(rinv+krsq-fr->c_rf);
207                              fscal            = qq*(rinv-2.0*krsq)*rinvsq;
208                              break;
209                              
210                          case 3:
211                              /* Tabulated coulomb */
212                              Y                = VFtab[nnn];     
213                              F                = VFtab[nnn+1];   
214                              Geps             = eps*VFtab[nnn+2];
215                              Heps2            = eps2*VFtab[nnn+3];
216                              nnn             += 4;
217                              Fp               = F+Geps+Heps2;   
218                              VV               = Y+eps*Fp;       
219                              FF               = Fp+Geps+2.0*Heps2;
220                              vcoul            = qq*VV;          
221                              fscal            = -qq*FF*tabscale*rinv;
222                              break;
223                              
224                          case 4:
225                              /* GB */
226                            gmx_fatal(FARGS,"Death & horror! GB generic interaction not implemented.\n");
227                            break;
228                            
229                          default:
230                              gmx_fatal(FARGS,"Death & horror! No generic coulomb interaction for ielec=%d.\n",ielec);
231                              break;
232                          }
233                          vctot            = vctot+vcoul;    
234                      } /* End of coulomb interactions */
235                      
236                      
237                      /* VdW interaction. ivdw==0 means no interaction */
238                      if (ivdw > 0)
239                      {
240                          tj               = nti+nvdwparam*type[aj];
241                          
242                          switch(ivdw)
243                          {
244                          case 1:
245                              /* Vanilla Lennard-Jones cutoff */
246                              c6               = vdwparam[tj];   
247                              c12              = vdwparam[tj+1]; 
248                              
249                              rinvsix          = rinvsq*rinvsq*rinvsq;
250                              Vvdw_disp        = c6*rinvsix;     
251                              Vvdw_rep         = c12*rinvsix*rinvsix;
252                              fscal           += (12.0*Vvdw_rep-6.0*Vvdw_disp)*rinvsq;
253                              Vvdwtot          = Vvdwtot+Vvdw_rep-Vvdw_disp;
254                              break;
255                              
256                          case 2:
257                              /* Buckingham */
258                              c6               = vdwparam[tj];   
259                              cexp1            = vdwparam[tj+1]; 
260                              cexp2            = vdwparam[tj+2]; 
261                              
262                              rinvsix          = rinvsq*rinvsq*rinvsq;
263                              Vvdw_disp        = c6*rinvsix;     
264                              br               = cexp2*rsq*rinv;
265                              Vvdw_rep         = cexp1*exp(-br); 
266                              fscal           += (br*Vvdw_rep-6.0*Vvdw_disp)*rinvsq;
267                              Vvdwtot          = Vvdwtot+Vvdw_rep-Vvdw_disp;
268                              break;
269                              
270                          case 3:
271                              /* Tabulated VdW */
272                              c6               = vdwparam[tj];   
273                              c12              = vdwparam[tj+1]; 
274                              
275                              Y                = VFtab[nnn];     
276                              F                = VFtab[nnn+1];   
277                              Geps             = eps*VFtab[nnn+2];
278                              Heps2            = eps2*VFtab[nnn+3];
279                              Fp               = F+Geps+Heps2;   
280                              VV               = Y+eps*Fp;       
281                              FF               = Fp+Geps+2.0*Heps2;
282                              Vvdw_disp        = c6*VV;          
283                              fijD             = c6*FF;          
284                              nnn             += 4;          
285                              Y                = VFtab[nnn];     
286                              F                = VFtab[nnn+1];   
287                              Geps             = eps*VFtab[nnn+2];
288                              Heps2            = eps2*VFtab[nnn+3];
289                              Fp               = F+Geps+Heps2;   
290                              VV               = Y+eps*Fp;       
291                              FF               = Fp+Geps+2.0*Heps2;
292                              Vvdw_rep         = c12*VV;         
293                              fijR             = c12*FF;         
294                              fscal           += -(fijD+fijR)*tabscale*rinv;
295                              Vvdwtot          = Vvdwtot + Vvdw_disp + Vvdw_rep;                                         
296                              break;
297                              
298                          default:
299                              gmx_fatal(FARGS,"Death & horror! No generic VdW interaction for ivdw=%d.\n",ivdw);
300                              break;
301                          }
302                      } /* end VdW interactions */
303                      
304                      
305                      tx               = fscal*dx;     
306                      ty               = fscal*dy;     
307                      tz               = fscal*dz;     
308                      f[i3+0]         += tx;
309                      f[i3+1]         += ty;
310                      f[i3+2]         += tz;
311                      f[j3+0]         -= tx;
312                      f[j3+1]         -= ty;
313                      f[j3+2]         -= tz;
314                      fix             += tx;
315                      fiy             += ty;
316                      fiz             += tz;
317                  }
318              }
319          }
320
321          fshift[is3]     += fix;
322          fshift[is3+1]   += fiy;
323          fshift[is3+2]   += fiz;
324          ggid             = nlist->gid[n];         
325          Vc[ggid]        += vctot;
326          Vvdw[ggid]      += Vvdwtot;
327      }
328     /* Estimate flops, average for generic cg kernel:
329      * 12  flops per outer iteration
330      * 100 flops per inner iteration
331      */
332     inc_nrnb(nrnb,eNR_NBKERNEL_FREE_ENERGY,nlist->nri*12 + nlist->jindex[n]*100);
333 }
334