1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
11 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
12 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
13 * Copyright (c) 2001-2004, The GROMACS development team,
14 * check out http://www.gromacs.org for more information.
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * If you want to redistribute modifications, please consider that
22 * scientific software is very special. Version control is crucial -
23 * bugs must be traceable. We will be happy to consider code for
24 * inclusion in the official distribution, but derived work must not
25 * be called official GROMACS. Details are found in the README & COPYING
26 * files - if they are missing, get the official version at www.gromacs.org.
28 * To help us fund GROMACS development, we humbly ask that you cite
29 * the papers on the package - you can find them in the top README file.
31 * For more info, check our website at http://www.gromacs.org
34 * Gallium Rubidium Oxygen Manganese Argon Carbon Silicon
54 typedef struct gmx_repl_ex
{
70 enum { ereTEMP
, ereLAMBDA
, ereNR
};
71 const char *erename
[ereNR
] = { "temperature", "lambda" };
73 static void repl_quantity(FILE *fplog
,const gmx_multisim_t
*ms
,
74 struct gmx_repl_ex
*re
,int ere
,real q
)
82 gmx_sum_sim(ms
->nsim
,qall
,ms
);
85 for(s
=1; s
<ms
->nsim
; s
++)
86 if (qall
[s
] != qall
[0])
90 if (re
->type
>= 0 && re
->type
< ereNR
) {
91 gmx_fatal(FARGS
,"For replica exchange both %s and %s differ",
92 erename
[re
->type
],erename
[ere
]);
94 /* Set the replica exchange type and quantities */
96 snew(re
->q
,re
->nrepl
);
97 for(s
=0; s
<ms
->nsim
; s
++)
105 gmx_repl_ex_t
init_replica_exchange(FILE *fplog
,
106 const gmx_multisim_t
*ms
,
107 const t_state
*state
,
108 const t_inputrec
*ir
,
109 int nst
,int init_seed
)
113 struct gmx_repl_ex
*re
;
115 fprintf(fplog
,"\nInitializing Replica Exchange\n");
117 if (ms
== NULL
|| ms
->nsim
== 1)
118 gmx_fatal(FARGS
,"Nothing to exchange with only one replica, maybe you forgot to set the -multi option of mdrun?");
123 re
->nrepl
= ms
->nsim
;
125 fprintf(fplog
,"Repl There are %d replicas:\n",re
->nrepl
);
127 check_multi_int(fplog
,ms
,state
->natoms
,"the number of atoms");
128 check_multi_int(fplog
,ms
,ir
->eI
,"the integrator");
129 check_multi_int(fplog
,ms
,ir
->init_step
+ir
->nsteps
,"init_step+nsteps");
130 check_multi_int(fplog
,ms
,(ir
->init_step
+nst
-1)/nst
,
131 "first exchange step: init_step/-replex");
132 check_multi_int(fplog
,ms
,ir
->etc
,"the temperature coupling");
133 check_multi_int(fplog
,ms
,ir
->opts
.ngtc
,
134 "the number of temperature coupling groups");
135 check_multi_int(fplog
,ms
,ir
->epc
,"the pressure coupling");
136 check_multi_int(fplog
,ms
,ir
->efep
,"free energy");
138 re
->temp
= ir
->opts
.ref_t
[0];
139 for(i
=1; (i
<ir
->opts
.ngtc
); i
++) {
140 if (ir
->opts
.ref_t
[i
] != re
->temp
) {
141 fprintf(fplog
,"\nWARNING: The temperatures of the different temperature coupling groups are not identical\n\n");
142 fprintf(stderr
,"\nWARNING: The temperatures of the different temperature coupling groups are not identical\n\n");
147 for(i
=0; i
<ereNR
; i
++)
152 repl_quantity(fplog
,ms
,re
,i
,re
->temp
);
155 if (ir
->efep
!= efepNO
)
157 repl_quantity(fplog
,ms
,re
,i
,ir
->init_lambda
);
161 gmx_incons("Unknown replica exchange quantity");
166 gmx_fatal(FARGS
,"The properties of the %d systems are all the same, there is nothing to exchange",re
->nrepl
);
172 please_cite(fplog
,"Hukushima96a");
173 if (ir
->epc
!= epcNO
)
176 fprintf(fplog
,"Repl Using Constant Pressure REMD.\n");
177 please_cite(fplog
,"Okabe2001a");
179 if (ir
->etc
== etcBERENDSEN
)
181 gmx_fatal(FARGS
,"REMD with the %s thermostat does not produce correct potential energy distributions, consider using the %s thermostat instead",
182 ETCOUPLTYPE(ir
->etc
),ETCOUPLTYPE(etcVRESCALE
));
186 if (ir
->delta_lambda
!= 0)
188 gmx_fatal(FARGS
,"delta_lambda is not zero");
194 snew(re
->pres
,re
->nrepl
);
195 if (ir
->epct
== epctSURFACETENSION
) {
196 pres
= ir
->ref_p
[ZZ
][ZZ
];
201 if (ir
->compress
[i
][i
] != 0) {
202 pres
+= ir
->ref_p
[i
][i
];
207 re
->pres
[re
->repl
] = pres
;
208 gmx_sum_sim(re
->nrepl
,re
->pres
,ms
);
211 snew(re
->ind
,re
->nrepl
);
212 /* Make an index for increasing temperature order */
213 for(i
=0; i
<re
->nrepl
; i
++)
215 for(i
=0; i
<re
->nrepl
; i
++) {
216 for(j
=i
+1; j
<re
->nrepl
; j
++) {
217 if (re
->q
[re
->ind
[j
]] < re
->q
[re
->ind
[i
]]) {
219 re
->ind
[i
] = re
->ind
[j
];
221 } else if (re
->q
[re
->ind
[j
]] == re
->q
[re
->ind
[i
]]) {
222 gmx_fatal(FARGS
,"Two replicas have identical %ss",erename
[re
->type
]);
226 fprintf(fplog
,"Repl ");
227 for(i
=0; i
<re
->nrepl
; i
++)
228 fprintf(fplog
," %3d ",re
->ind
[i
]);
231 fprintf(fplog
,"\nRepl T");
232 for(i
=0; i
<re
->nrepl
; i
++)
233 fprintf(fplog
," %5.1f",re
->q
[re
->ind
[i
]]);
236 fprintf(fplog
,"\nRepl l");
237 for(i
=0; i
<re
->nrepl
; i
++)
238 fprintf(fplog
," %5.3f",re
->q
[re
->ind
[i
]]);
241 gmx_incons("Unknown replica exchange quantity");
244 fprintf(fplog
,"\nRepl p");
245 for(i
=0; i
<re
->nrepl
; i
++)
247 fprintf(fplog
," %5.2f",re
->pres
[re
->ind
[i
]]);
250 for(i
=0; i
<re
->nrepl
; i
++)
252 if ((i
> 0) && (re
->pres
[re
->ind
[i
]] < re
->pres
[re
->ind
[i
-1]]))
254 gmx_fatal(FARGS
,"The reference pressure decreases with increasing temperature");
258 fprintf(fplog
,"\nRepl ");
261 if (init_seed
== -1) {
263 re
->seed
= make_seed();
266 gmx_sumi_sim(1,&(re
->seed
),ms
);
268 re
->seed
= init_seed
;
270 fprintf(fplog
,"\nRepl exchange interval: %d\n",re
->nst
);
271 fprintf(fplog
,"\nRepl random seed: %d\n",re
->seed
);
275 snew(re
->prob_sum
,re
->nrepl
);
276 snew(re
->nexchange
,re
->nrepl
);
279 "Repl below: x=exchange, pr=probability\n");
284 static void exchange_reals(const gmx_multisim_t
*ms
,int b
,real
*v
,int n
)
293 MPI_Sendrecv(v, n*sizeof(real),MPI_BYTE,MSRANK(ms,b),0,
294 buf,n*sizeof(real),MPI_BYTE,MSRANK(ms,b),0,
295 ms->mpi_comm_masters,MPI_STATUS_IGNORE);
300 MPI_Isend(v
,n
*sizeof(real
),MPI_BYTE
,MSRANK(ms
,b
),0,
301 ms
->mpi_comm_masters
,&mpi_req
);
302 MPI_Recv(buf
,n
*sizeof(real
),MPI_BYTE
,MSRANK(ms
,b
),0,
303 ms
->mpi_comm_masters
,MPI_STATUS_IGNORE
);
304 MPI_Wait(&mpi_req
,MPI_STATUS_IGNORE
);
313 static void exchange_doubles(const gmx_multisim_t
*ms
,int b
,double *v
,int n
)
322 MPI_Sendrecv(v, n*sizeof(double),MPI_BYTE,MSRANK(ms,b),0,
323 buf,n*sizeof(double),MPI_BYTE,MSRANK(ms,b),0,
324 ms->mpi_comm_masters,MPI_STATUS_IGNORE);
329 MPI_Isend(v
,n
*sizeof(double),MPI_BYTE
,MSRANK(ms
,b
),0,
330 ms
->mpi_comm_masters
,&mpi_req
);
331 MPI_Recv(buf
,n
*sizeof(double),MPI_BYTE
,MSRANK(ms
,b
),0,
332 ms
->mpi_comm_masters
,MPI_STATUS_IGNORE
);
333 MPI_Wait(&mpi_req
,MPI_STATUS_IGNORE
);
342 static void exchange_rvecs(const gmx_multisim_t
*ms
,int b
,rvec
*v
,int n
)
351 MPI_Sendrecv(v[0], n*sizeof(rvec),MPI_BYTE,MSRANK(ms,b),0,
352 buf[0],n*sizeof(rvec),MPI_BYTE,MSRANK(ms,b),0,
353 ms->mpi_comm_masters,MPI_STATUS_IGNORE);
358 MPI_Isend(v
[0],n
*sizeof(rvec
),MPI_BYTE
,MSRANK(ms
,b
),0,
359 ms
->mpi_comm_masters
,&mpi_req
);
360 MPI_Recv(buf
[0],n
*sizeof(rvec
),MPI_BYTE
,MSRANK(ms
,b
),0,
361 ms
->mpi_comm_masters
,MPI_STATUS_IGNORE
);
362 MPI_Wait(&mpi_req
,MPI_STATUS_IGNORE
);
366 copy_rvec(buf
[i
],v
[i
]);
371 static void exchange_state(const gmx_multisim_t
*ms
,int b
,t_state
*state
)
373 /* When t_state changes, this code should be updated. */
375 ngtc
= state
->ngtc
* state
->nhchainlength
;
376 nnhpres
= state
->nnhpres
* state
->nhchainlength
;
377 exchange_rvecs(ms
,b
,state
->box
,DIM
);
378 exchange_rvecs(ms
,b
,state
->box_rel
,DIM
);
379 exchange_rvecs(ms
,b
,state
->boxv
,DIM
);
380 exchange_reals(ms
,b
,&(state
->veta
),1);
381 exchange_reals(ms
,b
,&(state
->vol0
),1);
382 exchange_rvecs(ms
,b
,state
->svir_prev
,DIM
);
383 exchange_rvecs(ms
,b
,state
->fvir_prev
,DIM
);
384 exchange_rvecs(ms
,b
,state
->pres_prev
,DIM
);
385 exchange_doubles(ms
,b
,state
->nosehoover_xi
,ngtc
);
386 exchange_doubles(ms
,b
,state
->nosehoover_vxi
,ngtc
);
387 exchange_doubles(ms
,b
,state
->nhpres_xi
,nnhpres
);
388 exchange_doubles(ms
,b
,state
->nhpres_vxi
,nnhpres
);
389 exchange_doubles(ms
,b
,state
->therm_integral
,state
->ngtc
);
390 exchange_rvecs(ms
,b
,state
->x
,state
->natoms
);
391 exchange_rvecs(ms
,b
,state
->v
,state
->natoms
);
392 exchange_rvecs(ms
,b
,state
->sd_X
,state
->natoms
);
395 static void copy_rvecs(rvec
*s
,rvec
*d
,int n
)
403 copy_rvec(s
[i
],d
[i
]);
408 static void copy_doubles(const double *s
,double *d
,int n
)
421 #define scopy_rvecs(v,n) copy_rvecs(state->v,state_local->v,n);
422 #define scopy_doubles(v,n) copy_doubles(state->v,state_local->v,n);
424 static void copy_state_nonatomdata(t_state
*state
,t_state
*state_local
)
426 /* When t_state changes, this code should be updated. */
428 ngtc
= state
->ngtc
* state
->nhchainlength
;
429 nnhpres
= state
->nnhpres
* state
->nhchainlength
;
430 scopy_rvecs(box
,DIM
);
431 scopy_rvecs(box_rel
,DIM
);
432 scopy_rvecs(boxv
,DIM
);
433 state_local
->veta
= state
->veta
;
434 state_local
->vol0
= state
->vol0
;
435 scopy_rvecs(svir_prev
,DIM
);
436 scopy_rvecs(fvir_prev
,DIM
);
437 scopy_rvecs(pres_prev
,DIM
);
438 scopy_doubles(nosehoover_xi
,ngtc
);
439 scopy_doubles(nosehoover_vxi
,ngtc
);
440 scopy_doubles(nhpres_xi
,nnhpres
);
441 scopy_doubles(nhpres_vxi
,nnhpres
);
442 scopy_doubles(therm_integral
,state
->ngtc
);
443 scopy_rvecs(x
,state
->natoms
);
444 scopy_rvecs(v
,state
->natoms
);
445 scopy_rvecs(sd_X
,state
->natoms
);
448 static void scale_velocities(t_state
*state
,real fac
)
453 for(i
=0; i
<state
->natoms
; i
++)
454 svmul(fac
,state
->v
[i
],state
->v
[i
]);
457 static void pd_collect_state(const t_commrec
*cr
,t_state
*state
)
462 fprintf(debug
,"Collecting state before exchange\n");
463 shift
= cr
->nnodes
- cr
->npmenodes
- 1;
464 move_rvecs(cr
,FALSE
,FALSE
,GMX_LEFT
,GMX_RIGHT
,state
->x
,NULL
,shift
,NULL
);
466 move_rvecs(cr
,FALSE
,FALSE
,GMX_LEFT
,GMX_RIGHT
,state
->v
,NULL
,shift
,NULL
);
468 move_rvecs(cr
,FALSE
,FALSE
,GMX_LEFT
,GMX_RIGHT
,state
->sd_X
,NULL
,shift
,NULL
);
471 static void print_ind(FILE *fplog
,const char *leg
,int n
,int *ind
,bool *bEx
)
475 fprintf(fplog
,"Repl %2s %2d",leg
,ind
[0]);
477 fprintf(fplog
," %c %2d",(bEx
!=0 && bEx
[i
]) ? 'x' : ' ',ind
[i
]);
482 static void print_prob(FILE *fplog
,const char *leg
,int n
,real
*prob
)
487 fprintf(fplog
,"Repl %2s ",leg
);
490 sprintf(buf
,"%4.2f",prob
[i
]);
491 fprintf(fplog
," %3s",buf
[0]=='1' ? "1.0" : buf
+1);
499 static void print_count(FILE *fplog
,const char *leg
,int n
,int *count
)
503 fprintf(fplog
,"Repl %2s ",leg
);
505 fprintf(fplog
," %4d",count
[i
]);
510 static int get_replica_exchange(FILE *fplog
,const gmx_multisim_t
*ms
,
511 struct gmx_repl_ex
*re
,real
*ener
,real vol
,
515 real
*Epot
=NULL
,*Vol
=NULL
,*dvdl
=NULL
,*prob
;
516 real ediff
=0,delta
=0,dpV
=0,betaA
=0,betaB
=0;
520 fprintf(fplog
,"Replica exchange at step %d time %g\n",step
,time
);
524 snew(Epot
,re
->nrepl
);
526 Epot
[re
->repl
] = ener
[F_EPOT
];
528 gmx_sum_sim(re
->nrepl
,Epot
,ms
);
529 gmx_sum_sim(re
->nrepl
,Vol
,ms
);
532 snew(dvdl
,re
->nrepl
);
533 dvdl
[re
->repl
] = ener
[F_DVDL
];
534 gmx_sum_sim(re
->nrepl
,dvdl
,ms
);
539 snew(prob
,re
->nrepl
);
542 m
= (step
/ re
->nst
) % 2;
543 for(i
=1; i
<re
->nrepl
; i
++) {
546 bPrint
= (re
->repl
==a
|| re
->repl
==b
);
550 /* Use equations from:
551 * Okabe et. al. Chem. Phys. Lett. 335 (2001) 435-439
553 ediff
= Epot
[b
] - Epot
[a
];
554 betaA
= 1.0/(re
->q
[a
]*BOLTZ
);
555 betaB
= 1.0/(re
->q
[b
]*BOLTZ
);
556 delta
= (betaA
- betaB
)*ediff
;
559 /* Here we exchange based on a linear extrapolation of dV/dlambda.
560 * We would like to have the real energies
561 * from foreign lambda calculations.
563 ediff
= (dvdl
[a
] - dvdl
[b
])*(re
->q
[b
] - re
->q
[a
]);
564 delta
= ediff
/(BOLTZ
*re
->temp
);
567 gmx_incons("Unknown replica exchange quantity");
570 fprintf(fplog
,"Repl %d <-> %d dE = %10.3e",a
,b
,delta
);
572 dpV
= (betaA
*re
->pres
[a
]-betaB
*re
->pres
[b
])*(Vol
[b
]-Vol
[a
])/PRESFAC
;
574 fprintf(fplog
," dpV = %10.3e d = %10.3e",dpV
,delta
+ dpV
);
586 prob
[i
] = exp(-delta
);
587 bEx
[i
] = (rando(&(re
->seed
)) < prob
[i
]);
589 re
->prob_sum
[i
] += prob
[i
];
593 } else if (b
== re
->repl
) {
603 print_ind(fplog
,"ex",re
->nrepl
,re
->ind
,bEx
);
604 print_prob(fplog
,"pr",re
->nrepl
,prob
);
618 static void write_debug_x(t_state
*state
)
623 for(i
=0; i
<state
->natoms
; i
+=10)
624 fprintf(debug
,"dx %5d %10.5f %10.5f %10.5f\n",i
,state
->x
[i
][XX
],state
->x
[i
][YY
],state
->x
[i
][ZZ
]);
628 bool replica_exchange(FILE *fplog
,const t_commrec
*cr
,struct gmx_repl_ex
*re
,
629 t_state
*state
,real
*ener
,
630 t_state
*state_local
,
634 int exchange
=-1,shift
;
635 bool bExchanged
=FALSE
;
641 exchange
= get_replica_exchange(fplog
,ms
,re
,ener
,det(state
->box
),
643 bExchanged
= (exchange
>= 0);
649 MPI_Bcast(&bExchanged
,sizeof(bool),MPI_BYTE
,MASTERRANK(cr
),
650 cr
->mpi_comm_mygroup
);
656 /* Exchange the states */
660 /* Collect the global state on the master node */
661 if (DOMAINDECOMP(cr
))
663 dd_collect_state(cr
->dd
,state_local
,state
);
667 pd_collect_state(cr
,state
);
673 /* Exchange the global states between the master nodes */
676 fprintf(debug
,"Exchanging %d with %d\n",ms
->sim
,exchange
);
678 exchange_state(ms
,exchange
,state
);
680 if (re
->type
== ereTEMP
)
682 scale_velocities(state
,sqrt(re
->q
[ms
->sim
]/re
->q
[exchange
]));
686 /* With domain decomposition the global state is distributed later */
687 if (!DOMAINDECOMP(cr
))
689 /* Copy the global state to the local state data structure */
690 copy_state_nonatomdata(state
,state_local
);
694 bcast_state(cr
,state
,FALSE
);
702 void print_replica_exchange_statistics(FILE *fplog
,struct gmx_repl_ex
*re
)
707 fprintf(fplog
,"\nReplica exchange statistics\n");
708 fprintf(fplog
,"Repl %d attempts, %d odd, %d even\n",
709 re
->nattempt
[0]+re
->nattempt
[1],re
->nattempt
[1],re
->nattempt
[0]);
711 snew(prob
,re
->nrepl
);
713 fprintf(fplog
,"Repl average probabilities:\n");
714 for(i
=1; i
<re
->nrepl
; i
++) {
715 if (re
->nattempt
[i
%2] == 0)
718 prob
[i
] = re
->prob_sum
[i
]/re
->nattempt
[i
%2];
720 print_ind(fplog
,"",re
->nrepl
,re
->ind
,NULL
);
721 print_prob(fplog
,"",re
->nrepl
,prob
);
723 fprintf(fplog
,"Repl number of exchanges:\n");
724 print_ind(fplog
,"",re
->nrepl
,re
->ind
,NULL
);
725 print_count(fplog
,"",re
->nrepl
,re
->nexchange
);
727 fprintf(fplog
,"Repl average number of exchanges:\n");
728 for(i
=1; i
<re
->nrepl
; i
++) {
729 if (re
->nattempt
[i
%2] == 0)
732 prob
[i
] = ((real
)re
->nexchange
[i
])/re
->nattempt
[i
%2];
734 print_ind(fplog
,"",re
->nrepl
,re
->ind
,NULL
);
735 print_prob(fplog
,"",re
->nrepl
,prob
);