5ef4d5d229aabe7de030cf7cbe227ea7ef4aeb66
[alexxy/gromacs.git] / src / gromacs / gmxlib / rbin.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) 2010,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 /* This file is completely threadsafe - keep it that way! */
38 #include "gmxpre.h"
39
40 #include "gromacs/legacyheaders/typedefs.h"
41 #include "gromacs/legacyheaders/network.h"
42 #include "gromacs/legacyheaders/rbin.h"
43 #include "gromacs/utility/smalloc.h"
44
45 t_bin *mk_bin(void)
46 {
47     t_bin *b;
48
49     snew(b, 1);
50
51     return b;
52 }
53
54 void destroy_bin(t_bin *b)
55 {
56     if (b->maxreal > 0)
57     {
58         sfree(b->rbuf);
59     }
60
61     sfree(b);
62 }
63
64 void reset_bin(t_bin *b)
65 {
66     b->nreal = 0;
67 }
68
69 int add_binr(t_bin *b, int nr, real r[])
70 {
71 #define MULT 4
72     int     i, rest, index;
73     double *rbuf;
74
75     if (b->nreal+nr > b->maxreal)
76     {
77         b->maxreal = b->nreal+nr;
78         rest       = b->maxreal % MULT;
79         if (rest != 0)
80         {
81             b->maxreal += MULT-rest;
82         }
83         srenew(b->rbuf, b->maxreal);
84     }
85     /* Copy pointer */
86     rbuf = b->rbuf+b->nreal;
87     for (i = 0; (i < nr); i++)
88     {
89         rbuf[i] = r[i];
90     }
91
92     index     = b->nreal;
93     b->nreal += nr;
94
95     return index;
96 }
97
98 int add_bind(t_bin *b, int nr, double r[])
99 {
100 #define MULT 4
101     int     i, rest, index;
102     double *rbuf;
103
104     if (b->nreal+nr > b->maxreal)
105     {
106         b->maxreal = b->nreal+nr;
107         rest       = b->maxreal % MULT;
108         if (rest != 0)
109         {
110             b->maxreal += MULT-rest;
111         }
112         srenew(b->rbuf, b->maxreal);
113     }
114     /* Copy pointer */
115     rbuf = b->rbuf+b->nreal;
116     for (i = 0; (i < nr); i++)
117     {
118         rbuf[i] = r[i];
119     }
120
121     index     = b->nreal;
122     b->nreal += nr;
123
124     return index;
125 }
126
127 void sum_bin(t_bin *b, t_commrec *cr)
128 {
129     int i;
130
131     for (i = b->nreal; (i < b->maxreal); i++)
132     {
133         b->rbuf[i] = 0;
134     }
135     gmx_sumd(b->maxreal, b->rbuf, cr);
136 }
137
138 void extract_binr(t_bin *b, int index, int nr, real r[])
139 {
140     int     i;
141     double *rbuf;
142
143     rbuf = b->rbuf+index;
144     for (i = 0; (i < nr); i++)
145     {
146         r[i] = rbuf[i];
147     }
148 }
149
150 void extract_bind(t_bin *b, int index, int nr, double r[])
151 {
152     int     i;
153     double *rbuf;
154
155     rbuf = b->rbuf+index;
156     for (i = 0; (i < nr); i++)
157     {
158         r[i] = rbuf[i];
159     }
160 }
161
162 #ifdef DEBUGRBIN
163 int main(int argc, char *argv[])
164 {
165     t_commrec *cr;
166     t_bin     *rb;
167     double    *r;
168     rvec      *v;
169     int        k, i, ni, mi, n, m;
170
171     cr = init_par(&argc, argv);
172     n  = strtol(argv[1], NULL, 10);
173     m  = strtol(argv[2], NULL, 10);
174     fprintf(stdlog, "n=%d\n", n);
175     rb = mk_bin();
176     snew(r, n);
177     snew(v, m);
178
179     for (k = 0; (k < 3); k++)
180     {
181         fprintf(stdlog, "\nk=%d\n", k);
182         reset_bin(rb);
183
184         for (i = 0; (i < n); i++)
185         {
186             r[i] = i+k;
187         }
188         for (i = 0; (i < m); i++)
189         {
190             v[i][XX] = 4*i+k;
191             v[i][YY] = 4*i+k+1;
192             v[i][ZZ] = 4*i+k+2;
193         }
194
195         ni = add_bind(stdlog, rb, n, r);
196         mi = add_binr(stdlog, rb, DIM*m, v[0]);
197
198         sum_bin(rb, cr);
199
200         extract_bind(rb, ni, n, r);
201         extract_binr(rb, mi, DIM*m, v[0]);
202
203         for (i = 0; (i < n); i++)
204         {
205             fprintf(stdlog, "r[%d] = %e\n", i, r[i]);
206         }
207         for (i = 0; (i < m); i++)
208         {
209             fprintf(stdlog, "v[%d] = (%e,%e,%e)\n", i, v[i][XX], v[i][YY], v[i][ZZ]);
210         }
211     }
212     fflush(stdlog);
213
214     return 0;
215 }
216 #endif