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)])
71 cur = (cr->nodeid + pd_shift(cr)) % cr->nnodes;
76 for(i=0; (i<shift); i++) {
86 for(j=j0; (j<j1); j++) {
90 /* Forward pulse around the ring, to increasing NODE number */
94 GMX_RIGHT,vecs[index[cur ]],HOMENRI(index,cur )*DIM,
95 GMX_LEFT, buf [index[prev]],HOMENRI(index,prev)*DIM);
98 GMX_RIGHT,vecs[index[cur ]],HOMENRI(index,cur )*DIM,
99 GMX_LEFT, vecs[index[prev]],HOMENRI(index,prev)*DIM);
100 /* Wait for communication to end */
101 gmx_wait(cr, right,left);
104 /* Backward pulse around the ring, to decreasing NODE number */
108 GMX_LEFT, vecs[index[cur ]],HOMENRI(index,cur )*DIM,
109 GMX_RIGHT,buf [index[next]],HOMENRI(index,next)*DIM);
112 GMX_LEFT, vecs[index[cur ]],HOMENRI(index,cur )*DIM,
113 GMX_RIGHT,vecs[index[next]],HOMENRI(index,next)*DIM);
114 /* Wait for communication to end */
115 gmx_wait(cr, left,right);
118 /* Actual summation */
120 for(j=j0; (j<j1); j++) {
121 rvec_inc(vecs[j],buf[j]);
131 inc_nrnb(nrnb,eNR_FSUM,nsum);
137 void move_reals(const t_commrec *cr,gmx_bool bForward,gmx_bool bSum,
138 int left,int right,real reals[],real buf[],
139 int shift,t_nrnb *nrnb)
141 int i,j,j0=137,j1=391;
144 #define next ((cur + 1) % cr->nnodes)
145 #define prev ((cur - 1 + cr->nnodes) % cr->nnodes)
147 #define HOMENRI(ind,i) ((ind)[(i)+1] - (ind)[(i)])
149 index = pd_index(cr);
153 cur = (cr->nodeid + pd_shift(cr)) % cr->nnodes;
161 for(i=0; (i<shift); i++)
175 for(j=j0; (j<j1); j++)
180 /* Forward pulse around the ring, to increasing NODE number */
185 GMX_RIGHT,reals+index[cur ],HOMENRI(index,cur ),
186 GMX_LEFT, buf+index[prev],HOMENRI(index,prev));
191 GMX_RIGHT,reals+index[cur ],HOMENRI(index,cur ),
192 GMX_LEFT, reals+index[prev],HOMENRI(index,prev));
194 /* Wait for communication to end */
195 gmx_wait(cr, right,left);
199 /* Backward pulse around the ring, to decreasing NODE number */
203 GMX_LEFT, reals+index[cur ],HOMENRI(index,cur ),
204 GMX_RIGHT,buf+index[next],HOMENRI(index,next));
209 GMX_LEFT, reals+index[cur ],HOMENRI(index,cur ),
210 GMX_RIGHT,reals+index[next],HOMENRI(index,next));
211 /* Wait for communication to end */
213 gmx_wait(cr, left,right);
216 /* Actual summation */
219 for(j=j0; (j<j1); j++)
237 inc_nrnb(nrnb,eNR_FSUM,nsum/3);
243 void move_x(FILE *log,const t_commrec *cr,
244 int left,int right,rvec x[],
247 move_rvecs(cr,FALSE,FALSE,left,right,x,NULL,pd_shift(cr),nrnb);
248 move_rvecs(cr,TRUE, FALSE,left,right,x,NULL,pd_bshift(cr),nrnb);
253 void move_rborn(FILE *log,const t_commrec *cr,
254 int left,int right,real rborn[],
257 move_reals(cr,FALSE,FALSE,left,right,rborn,NULL,pd_shift(cr),nrnb);
258 move_reals(cr,TRUE, FALSE,left,right,rborn,NULL,pd_bshift(cr),nrnb);
263 void move_f(FILE *log,const t_commrec *cr,
264 int left,int right,rvec f[],rvec fadd[],
267 move_rvecs(cr,TRUE, TRUE,left,right,f,fadd,pd_shift(cr),nrnb);
268 move_rvecs(cr,FALSE,TRUE,left,right,f,fadd,pd_bshift(cr),nrnb);
273 void move_gpol(FILE *log,const t_commrec *cr,
274 int left,int right,real gpol[],real gpol_add[],
277 move_reals(cr,TRUE, TRUE,left,right,gpol,gpol_add,pd_shift(cr),nrnb);
278 move_reals(cr,FALSE,TRUE,left,right,gpol,gpol_add,pd_bshift(cr),nrnb);
284 void move_cgcm(FILE *log,const t_commrec *cr,rvec cg_cm[])
290 #define next ((cur+1) % cr->nnodes)
292 cgindex = pd_cgindex(cr);
294 for(i=0; (i<cr->nnodes-1); i++) {
295 start = cgindex[cur];
296 nr = cgindex[cur+1] - start;
298 gmx_tx(cr,GMX_LEFT, cg_cm[start], nr*sizeof(cg_cm[0]));
300 fprintf(log,"move_cgcm: TX start=%d, nr=%d\n",start,nr);
302 start = cgindex[next];
303 nr = cgindex[next+1] - start;
305 gmx_rx(cr,GMX_RIGHT,cg_cm[start], nr*sizeof(cg_cm[0]));
307 fprintf(log,"move_cgcm: RX start=%d, nr=%d\n",start,nr);
309 gmx_tx_wait(cr,GMX_LEFT);
310 gmx_rx_wait(cr,GMX_RIGHT);
313 fprintf(debug,"cgcm[0][XX] %f\n",cg_cm[0][XX]);