Merge branch release-4-6 into master
[alexxy/gromacs.git] / src / gromacs / mdlib / nbnxn_kernels / nbnxn_kernel_common.c
1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
2  *
3  *
4  *                This source code is part of
5  *
6  *                 G   R   O   M   A   C   S
7  *
8  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
9  * Copyright (c) 2001-2009, The GROMACS Development Team
10  *
11  * Gromacs is a library for molecular simulation and trajectory analysis,
12  * written by Erik Lindahl, David van der Spoel, Berk Hess, and others - for
13  * a full list of developers and information, check out http://www.gromacs.org
14  *
15  * This program is free software; you can redistribute it and/or modify it under
16  * the terms of the GNU Lesser General Public License as published by the Free
17  * Software Foundation; either version 2 of the License, or (at your option) any
18  * later version.
19  * As a special exception, you may use this file as part of a free software
20  * library without restriction.  Specifically, if other files instantiate
21  * templates or use macros or inline functions from this file, or you compile
22  * this file and link it with other files to produce an executable, this
23  * file does not by itself cause the resulting executable to be covered by
24  * the GNU Lesser General Public License.
25  *
26  * In plain-speak: do not worry about classes/macros/templates either - only
27  * changes to the library have to be LGPL, not an application linking with it.
28  *
29  * To help fund GROMACS development, we humbly ask that you cite
30  * the papers people have written on it - you can find them on the website!
31  */
32 #ifdef HAVE_CONFIG_H
33 #include <config.h>
34 #endif
35
36 #include "nbnxn_kernel_common.h"
37
38 static void
39 clear_f_all(const nbnxn_atomdata_t *nbat, real *f)
40 {
41     int i;
42
43     for (i = 0; i < nbat->natoms*nbat->fstride; i++)
44     {
45         f[i] = 0;
46     }
47 }
48
49 static void
50 clear_f_flagged(const nbnxn_atomdata_t *nbat, int output_index, real *f)
51 {
52     const nbnxn_buffer_flags_t *flags;
53     unsigned                    our_flag;
54     int g, b, a0, a1, i;
55
56     flags = &nbat->buffer_flags;
57
58     our_flag = (1U << output_index);
59
60     for (b = 0; b < flags->nflag; b++)
61     {
62         if (flags->flag[b] & our_flag)
63         {
64             a0 = b*NBNXN_BUFFERFLAG_SIZE;
65             a1 = a0 + NBNXN_BUFFERFLAG_SIZE;
66             for (i = a0*nbat->fstride; i < a1*nbat->fstride; i++)
67             {
68                 f[i] = 0;
69             }
70         }
71     }
72 }
73
74 void
75 clear_f(const nbnxn_atomdata_t *nbat, int output_index, real *f)
76 {
77     if (nbat->bUseBufferFlags)
78     {
79         clear_f_flagged(nbat, output_index, f);
80     }
81     else
82     {
83         clear_f_all(nbat, f);
84     }
85 }
86
87 void
88 clear_fshift(real *fshift)
89 {
90     int i;
91
92     for (i = 0; i < SHIFTS*DIM; i++)
93     {
94         fshift[i] = 0;
95     }
96 }
97
98 void
99 reduce_energies_over_lists(const nbnxn_atomdata_t     *nbat,
100                            int                         nlist,
101                            real                       *Vvdw,
102                            real                       *Vc)
103 {
104     int nb;
105     int i, j, ind, indr;
106
107     for (nb = 0; nb < nlist; nb++)
108     {
109         for (i = 0; i < nbat->nenergrp; i++)
110         {
111             /* Reduce the diagonal terms */
112             ind        = i*nbat->nenergrp + i;
113             Vvdw[ind] += nbat->out[nb].Vvdw[ind];
114             Vc[ind]   += nbat->out[nb].Vc[ind];
115
116             /* Reduce the off-diagonal terms */
117             for (j = i+1; j < nbat->nenergrp; j++)
118             {
119                 /* The output should contain only one off-diagonal part */
120                 ind        = i*nbat->nenergrp + j;
121                 indr       = j*nbat->nenergrp + i;
122                 Vvdw[ind] += nbat->out[nb].Vvdw[ind] + nbat->out[nb].Vvdw[indr];
123                 Vc[ind]   += nbat->out[nb].Vc[ind]   + nbat->out[nb].Vc[indr];
124             }
125         }
126     }
127 }