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
,bool bForward
,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
,bool bForward
,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
]);