3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
10 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12 * Copyright (c) 2001-2004, The GROMACS development team,
13 * check out http://www.gromacs.org for more information.
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * If you want to redistribute modifications, please consider that
21 * scientific software is very special. Version control is crucial -
22 * bugs must be traceable. We will be happy to consider code for
23 * inclusion in the official distribution, but derived work must not
24 * be called official GROMACS. Details are found in the README & COPYING
25 * files - if they are missing, get the official version at www.gromacs.org.
27 * To help us fund GROMACS development, we humbly ask that you cite
28 * the papers on the package - you can find them in the top README file.
30 * For more info, check our website at http://www.gromacs.org
33 * GROningen Mixture of Alchemy and Childrens' Stories
35 /* This file is completely threadsafe - keep it that way! */
47 #include "gmx_fatal.h"
56 void move_rvecs(const t_commrec *cr, gmx_bool bForward, gmx_bool bSum,
57 int left, int right, rvec vecs[], rvec buf[],
58 int shift, t_nrnb *nrnb)
60 int i, j, j0 = 137, j1 = 391;
63 #define next ((cur + 1) % cr->nnodes)
64 #define prev ((cur - 1 + cr->nnodes) % cr->nnodes)
66 #define HOMENRI(ind, i) ((ind)[(i)+1] - (ind)[(i)])
72 cur = (cr->nodeid + pd_shift(cr)) % cr->nnodes;
80 for (i = 0; (i < shift); i++)
94 for (j = j0; (j < j1); j++)
99 /* Forward pulse around the ring, to increasing NODE number */
105 GMX_RIGHT, vecs[index[cur ]], HOMENRI(index, cur )*DIM,
106 GMX_LEFT, buf [index[prev]], HOMENRI(index, prev)*DIM);
111 GMX_RIGHT, vecs[index[cur ]], HOMENRI(index, cur )*DIM,
112 GMX_LEFT, vecs[index[prev]], HOMENRI(index, prev)*DIM);
114 /* Wait for communication to end */
115 gmx_wait(cr, right, left);
118 /* Backward pulse around the ring, to decreasing NODE number */
124 GMX_LEFT, vecs[index[cur ]], HOMENRI(index, cur )*DIM,
125 GMX_RIGHT, buf [index[next]], HOMENRI(index, next)*DIM);
130 GMX_LEFT, vecs[index[cur ]], HOMENRI(index, cur )*DIM,
131 GMX_RIGHT, vecs[index[next]], HOMENRI(index, next)*DIM);
133 /* Wait for communication to end */
134 gmx_wait(cr, left, right);
137 /* Actual summation */
140 for (j = j0; (j < j1); j++)
142 rvec_inc(vecs[j], buf[j]);
157 inc_nrnb(nrnb, eNR_FSUM, nsum);
164 void move_reals(const t_commrec *cr, gmx_bool bForward, gmx_bool bSum,
165 int left, int right, real reals[], real buf[],
166 int shift, t_nrnb *nrnb)
168 int i, j, j0 = 137, j1 = 391;
171 #define next ((cur + 1) % cr->nnodes)
172 #define prev ((cur - 1 + cr->nnodes) % cr->nnodes)
174 #define HOMENRI(ind, i) ((ind)[(i)+1] - (ind)[(i)])
176 index = pd_index(cr);
180 cur = (cr->nodeid + pd_shift(cr)) % cr->nnodes;
188 for (i = 0; (i < shift); i++)
202 for (j = j0; (j < j1); j++)
207 /* Forward pulse around the ring, to increasing NODE number */
213 GMX_RIGHT, reals+index[cur ], HOMENRI(index, cur ),
214 GMX_LEFT, buf+index[prev], HOMENRI(index, prev));
219 GMX_RIGHT, reals+index[cur ], HOMENRI(index, cur ),
220 GMX_LEFT, reals+index[prev], HOMENRI(index, prev));
222 /* Wait for communication to end */
223 gmx_wait(cr, right, left);
227 /* Backward pulse around the ring, to decreasing NODE number */
231 GMX_LEFT, reals+index[cur ], HOMENRI(index, cur ),
232 GMX_RIGHT, buf+index[next], HOMENRI(index, next));
237 GMX_LEFT, reals+index[cur ], HOMENRI(index, cur ),
238 GMX_RIGHT, reals+index[next], HOMENRI(index, next));
239 /* Wait for communication to end */
241 gmx_wait(cr, left, right);
244 /* Actual summation */
247 for (j = j0; (j < j1); j++)
265 inc_nrnb(nrnb, eNR_FSUM, nsum/3);
271 void move_x(FILE *log, const t_commrec *cr,
272 int left, int right, rvec x[],
275 move_rvecs(cr, FALSE, FALSE, left, right, x, NULL, pd_shift(cr), nrnb);
276 move_rvecs(cr, TRUE, FALSE, left, right, x, NULL, pd_bshift(cr), nrnb);
281 void move_rborn(FILE *log, const t_commrec *cr,
282 int left, int right, real rborn[],
285 move_reals(cr, FALSE, FALSE, left, right, rborn, NULL, pd_shift(cr), nrnb);
286 move_reals(cr, TRUE, FALSE, left, right, rborn, NULL, pd_bshift(cr), nrnb);
291 void move_f(FILE *log, const t_commrec *cr,
292 int left, int right, rvec f[], rvec fadd[],
295 move_rvecs(cr, TRUE, TRUE, left, right, f, fadd, pd_shift(cr), nrnb);
296 move_rvecs(cr, FALSE, TRUE, left, right, f, fadd, pd_bshift(cr), nrnb);
301 void move_gpol(FILE *log, const t_commrec *cr,
302 int left, int right, real gpol[], real gpol_add[],
305 move_reals(cr, TRUE, TRUE, left, right, gpol, gpol_add, pd_shift(cr), nrnb);
306 move_reals(cr, FALSE, TRUE, left, right, gpol, gpol_add, pd_bshift(cr), nrnb);
312 void move_cgcm(FILE *log, const t_commrec *cr, rvec cg_cm[])
315 int cur = cr->nodeid;
318 #define next ((cur+1) % cr->nnodes)
320 cgindex = pd_cgindex(cr);
322 for (i = 0; (i < cr->nnodes-1); i++)
324 start = cgindex[cur];
325 nr = cgindex[cur+1] - start;
327 gmx_tx(cr, GMX_LEFT, cg_cm[start], nr*sizeof(cg_cm[0]));
329 fprintf(log, "move_cgcm: TX start=%d, nr=%d\n", start, nr);
331 start = cgindex[next];
332 nr = cgindex[next+1] - start;
334 gmx_rx(cr, GMX_RIGHT, cg_cm[start], nr*sizeof(cg_cm[0]));
336 fprintf(log, "move_cgcm: RX start=%d, nr=%d\n", start, nr);
338 gmx_tx_wait(cr, GMX_LEFT);
339 gmx_rx_wait(cr, GMX_RIGHT);
343 fprintf(debug, "cgcm[0][XX] %f\n", cg_cm[0][XX]);