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
71 enum { ereTEMP
, ereLAMBDA
, ereNR
};
72 const char *erename
[ereNR
] = { "temperature", "lambda" };
74 static void repl_quantity(FILE *fplog
,const gmx_multisim_t
*ms
,
75 struct gmx_repl_ex
*re
,int ere
,real q
)
83 gmx_sum_sim(ms
->nsim
,qall
,ms
);
86 for(s
=1; s
<ms
->nsim
; s
++)
88 if (qall
[s
] != qall
[0])
95 if (re
->type
>= 0 && re
->type
< ereNR
)
97 gmx_fatal(FARGS
,"For replica exchange both %s and %s differ",
98 erename
[re
->type
],erename
[ere
]);
102 /* Set the replica exchange type and quantities */
104 snew(re
->q
,re
->nrepl
);
105 for(s
=0; s
<ms
->nsim
; s
++)
116 gmx_repl_ex_t
init_replica_exchange(FILE *fplog
,
117 const gmx_multisim_t
*ms
,
118 const t_state
*state
,
119 const t_inputrec
*ir
,
120 int nst
,int init_seed
)
124 struct gmx_repl_ex
*re
;
126 fprintf(fplog
,"\nInitializing Replica Exchange\n");
128 if (ms
== NULL
|| ms
->nsim
== 1)
130 gmx_fatal(FARGS
,"Nothing to exchange with only one replica, maybe you forgot to set the -multi option of mdrun?");
136 re
->nrepl
= ms
->nsim
;
138 fprintf(fplog
,"Repl There are %d replicas:\n",re
->nrepl
);
140 check_multi_int(fplog
,ms
,state
->natoms
,"the number of atoms");
141 check_multi_int(fplog
,ms
,ir
->eI
,"the integrator");
142 check_multi_large_int(fplog
,ms
,ir
->init_step
+ir
->nsteps
,"init_step+nsteps");
143 check_multi_large_int(fplog
,ms
,(ir
->init_step
+nst
-1)/nst
,
144 "first exchange step: init_step/-replex");
145 check_multi_int(fplog
,ms
,ir
->etc
,"the temperature coupling");
146 check_multi_int(fplog
,ms
,ir
->opts
.ngtc
,
147 "the number of temperature coupling groups");
148 check_multi_int(fplog
,ms
,ir
->epc
,"the pressure coupling");
149 check_multi_int(fplog
,ms
,ir
->efep
,"free energy");
151 re
->temp
= ir
->opts
.ref_t
[0];
152 for(i
=1; (i
<ir
->opts
.ngtc
); i
++)
154 if (ir
->opts
.ref_t
[i
] != re
->temp
)
156 fprintf(fplog
,"\nWARNING: The temperatures of the different temperature coupling groups are not identical\n\n");
157 fprintf(stderr
,"\nWARNING: The temperatures of the different temperature coupling groups are not identical\n\n");
162 for(i
=0; i
<ereNR
; i
++)
167 repl_quantity(fplog
,ms
,re
,i
,re
->temp
);
170 if (ir
->efep
!= efepNO
)
172 repl_quantity(fplog
,ms
,re
,i
,ir
->init_lambda
);
176 gmx_incons("Unknown replica exchange quantity");
181 gmx_fatal(FARGS
,"The properties of the %d systems are all the same, there is nothing to exchange",re
->nrepl
);
187 please_cite(fplog
,"Hukushima96a");
188 if (ir
->epc
!= epcNO
)
191 fprintf(fplog
,"Repl Using Constant Pressure REMD.\n");
192 please_cite(fplog
,"Okabe2001a");
194 if (ir
->etc
== etcBERENDSEN
)
196 gmx_fatal(FARGS
,"REMD with the %s thermostat does not produce correct potential energy distributions, consider using the %s thermostat instead",
197 ETCOUPLTYPE(ir
->etc
),ETCOUPLTYPE(etcVRESCALE
));
201 if (ir
->delta_lambda
!= 0)
203 gmx_fatal(FARGS
,"delta_lambda is not zero");
210 snew(re
->pres
,re
->nrepl
);
211 if (ir
->epct
== epctSURFACETENSION
)
213 pres
= ir
->ref_p
[ZZ
][ZZ
];
221 if (ir
->compress
[i
][i
] != 0)
223 pres
+= ir
->ref_p
[i
][i
];
229 re
->pres
[re
->repl
] = pres
;
230 gmx_sum_sim(re
->nrepl
,re
->pres
,ms
);
233 snew(re
->ind
,re
->nrepl
);
234 /* Make an index for increasing temperature order */
235 for(i
=0; i
<re
->nrepl
; i
++)
239 for(i
=0; i
<re
->nrepl
; i
++)
241 for(j
=i
+1; j
<re
->nrepl
; j
++)
243 if (re
->q
[re
->ind
[j
]] < re
->q
[re
->ind
[i
]])
246 re
->ind
[i
] = re
->ind
[j
];
249 else if (re
->q
[re
->ind
[j
]] == re
->q
[re
->ind
[i
]])
251 gmx_fatal(FARGS
,"Two replicas have identical %ss",erename
[re
->type
]);
255 fprintf(fplog
,"Repl ");
256 for(i
=0; i
<re
->nrepl
; i
++)
258 fprintf(fplog
," %3d ",re
->ind
[i
]);
263 fprintf(fplog
,"\nRepl T");
264 for(i
=0; i
<re
->nrepl
; i
++)
266 fprintf(fplog
," %5.1f",re
->q
[re
->ind
[i
]]);
270 fprintf(fplog
,"\nRepl l");
271 for(i
=0; i
<re
->nrepl
; i
++)
273 fprintf(fplog
," %5.3f",re
->q
[re
->ind
[i
]]);
277 gmx_incons("Unknown replica exchange quantity");
281 fprintf(fplog
,"\nRepl p");
282 for(i
=0; i
<re
->nrepl
; i
++)
284 fprintf(fplog
," %5.2f",re
->pres
[re
->ind
[i
]]);
287 for(i
=0; i
<re
->nrepl
; i
++)
289 if ((i
> 0) && (re
->pres
[re
->ind
[i
]] < re
->pres
[re
->ind
[i
-1]]))
291 gmx_fatal(FARGS
,"The reference pressure decreases with increasing temperature");
295 fprintf(fplog
,"\nRepl ");
302 re
->seed
= make_seed();
308 gmx_sumi_sim(1,&(re
->seed
),ms
);
312 re
->seed
= init_seed
;
314 fprintf(fplog
,"\nRepl exchange interval: %d\n",re
->nst
);
315 fprintf(fplog
,"\nRepl random seed: %d\n",re
->seed
);
319 snew(re
->prob_sum
,re
->nrepl
);
320 snew(re
->nexchange
,re
->nrepl
);
322 fprintf(fplog
,"Repl below: x=exchange, pr=probability\n");
327 static void exchange_reals(const gmx_multisim_t
*ms
,int b
,real
*v
,int n
)
337 MPI_Sendrecv(v, n*sizeof(real),MPI_BYTE,MSRANK(ms,b),0,
338 buf,n*sizeof(real),MPI_BYTE,MSRANK(ms,b),0,
339 ms->mpi_comm_masters,MPI_STATUS_IGNORE);
344 MPI_Isend(v
,n
*sizeof(real
),MPI_BYTE
,MSRANK(ms
,b
),0,
345 ms
->mpi_comm_masters
,&mpi_req
);
346 MPI_Recv(buf
,n
*sizeof(real
),MPI_BYTE
,MSRANK(ms
,b
),0,
347 ms
->mpi_comm_masters
,MPI_STATUS_IGNORE
);
348 MPI_Wait(&mpi_req
,MPI_STATUS_IGNORE
);
359 static void exchange_doubles(const gmx_multisim_t
*ms
,int b
,double *v
,int n
)
369 MPI_Sendrecv(v, n*sizeof(double),MPI_BYTE,MSRANK(ms,b),0,
370 buf,n*sizeof(double),MPI_BYTE,MSRANK(ms,b),0,
371 ms->mpi_comm_masters,MPI_STATUS_IGNORE);
376 MPI_Isend(v
,n
*sizeof(double),MPI_BYTE
,MSRANK(ms
,b
),0,
377 ms
->mpi_comm_masters
,&mpi_req
);
378 MPI_Recv(buf
,n
*sizeof(double),MPI_BYTE
,MSRANK(ms
,b
),0,
379 ms
->mpi_comm_masters
,MPI_STATUS_IGNORE
);
380 MPI_Wait(&mpi_req
,MPI_STATUS_IGNORE
);
391 static void exchange_rvecs(const gmx_multisim_t
*ms
,int b
,rvec
*v
,int n
)
401 MPI_Sendrecv(v[0], n*sizeof(rvec),MPI_BYTE,MSRANK(ms,b),0,
402 buf[0],n*sizeof(rvec),MPI_BYTE,MSRANK(ms,b),0,
403 ms->mpi_comm_masters,MPI_STATUS_IGNORE);
408 MPI_Isend(v
[0],n
*sizeof(rvec
),MPI_BYTE
,MSRANK(ms
,b
),0,
409 ms
->mpi_comm_masters
,&mpi_req
);
410 MPI_Recv(buf
[0],n
*sizeof(rvec
),MPI_BYTE
,MSRANK(ms
,b
),0,
411 ms
->mpi_comm_masters
,MPI_STATUS_IGNORE
);
412 MPI_Wait(&mpi_req
,MPI_STATUS_IGNORE
);
417 copy_rvec(buf
[i
],v
[i
]);
423 static void exchange_state(const gmx_multisim_t
*ms
,int b
,t_state
*state
)
425 /* When t_state changes, this code should be updated. */
427 ngtc
= state
->ngtc
* state
->nhchainlength
;
428 nnhpres
= state
->nnhpres
* state
->nhchainlength
;
429 exchange_rvecs(ms
,b
,state
->box
,DIM
);
430 exchange_rvecs(ms
,b
,state
->box_rel
,DIM
);
431 exchange_rvecs(ms
,b
,state
->boxv
,DIM
);
432 exchange_reals(ms
,b
,&(state
->veta
),1);
433 exchange_reals(ms
,b
,&(state
->vol0
),1);
434 exchange_rvecs(ms
,b
,state
->svir_prev
,DIM
);
435 exchange_rvecs(ms
,b
,state
->fvir_prev
,DIM
);
436 exchange_rvecs(ms
,b
,state
->pres_prev
,DIM
);
437 exchange_doubles(ms
,b
,state
->nosehoover_xi
,ngtc
);
438 exchange_doubles(ms
,b
,state
->nosehoover_vxi
,ngtc
);
439 exchange_doubles(ms
,b
,state
->nhpres_xi
,nnhpres
);
440 exchange_doubles(ms
,b
,state
->nhpres_vxi
,nnhpres
);
441 exchange_doubles(ms
,b
,state
->therm_integral
,state
->ngtc
);
442 exchange_rvecs(ms
,b
,state
->x
,state
->natoms
);
443 exchange_rvecs(ms
,b
,state
->v
,state
->natoms
);
444 exchange_rvecs(ms
,b
,state
->sd_X
,state
->natoms
);
447 static void copy_rvecs(rvec
*s
,rvec
*d
,int n
)
455 copy_rvec(s
[i
],d
[i
]);
460 static void copy_doubles(const double *s
,double *d
,int n
)
473 #define scopy_rvecs(v,n) copy_rvecs(state->v,state_local->v,n);
474 #define scopy_doubles(v,n) copy_doubles(state->v,state_local->v,n);
476 static void copy_state_nonatomdata(t_state
*state
,t_state
*state_local
)
478 /* When t_state changes, this code should be updated. */
480 ngtc
= state
->ngtc
* state
->nhchainlength
;
481 nnhpres
= state
->nnhpres
* state
->nhchainlength
;
482 scopy_rvecs(box
,DIM
);
483 scopy_rvecs(box_rel
,DIM
);
484 scopy_rvecs(boxv
,DIM
);
485 state_local
->veta
= state
->veta
;
486 state_local
->vol0
= state
->vol0
;
487 scopy_rvecs(svir_prev
,DIM
);
488 scopy_rvecs(fvir_prev
,DIM
);
489 scopy_rvecs(pres_prev
,DIM
);
490 scopy_doubles(nosehoover_xi
,ngtc
);
491 scopy_doubles(nosehoover_vxi
,ngtc
);
492 scopy_doubles(nhpres_xi
,nnhpres
);
493 scopy_doubles(nhpres_vxi
,nnhpres
);
494 scopy_doubles(therm_integral
,state
->ngtc
);
495 scopy_rvecs(x
,state
->natoms
);
496 scopy_rvecs(v
,state
->natoms
);
497 scopy_rvecs(sd_X
,state
->natoms
);
500 static void scale_velocities(t_state
*state
,real fac
)
506 for(i
=0; i
<state
->natoms
; i
++)
508 svmul(fac
,state
->v
[i
],state
->v
[i
]);
513 static void pd_collect_state(const t_commrec
*cr
,t_state
*state
)
519 fprintf(debug
,"Collecting state before exchange\n");
521 shift
= cr
->nnodes
- cr
->npmenodes
- 1;
522 move_rvecs(cr
,FALSE
,FALSE
,GMX_LEFT
,GMX_RIGHT
,state
->x
,NULL
,shift
,NULL
);
525 move_rvecs(cr
,FALSE
,FALSE
,GMX_LEFT
,GMX_RIGHT
,state
->v
,NULL
,shift
,NULL
);
529 move_rvecs(cr
,FALSE
,FALSE
,GMX_LEFT
,GMX_RIGHT
,state
->sd_X
,NULL
,shift
,NULL
);
533 static void print_ind(FILE *fplog
,const char *leg
,int n
,int *ind
,gmx_bool
*bEx
)
537 fprintf(fplog
,"Repl %2s %2d",leg
,ind
[0]);
540 fprintf(fplog
," %c %2d",(bEx
!=0 && bEx
[i
]) ? 'x' : ' ',ind
[i
]);
545 static void print_prob(FILE *fplog
,const char *leg
,int n
,real
*prob
)
550 fprintf(fplog
,"Repl %2s ",leg
);
555 sprintf(buf
,"%4.2f",prob
[i
]);
556 fprintf(fplog
," %3s",buf
[0]=='1' ? "1.0" : buf
+1);
566 static void print_count(FILE *fplog
,const char *leg
,int n
,int *count
)
570 fprintf(fplog
,"Repl %2s ",leg
);
573 fprintf(fplog
," %4d",count
[i
]);
578 static int get_replica_exchange(FILE *fplog
,const gmx_multisim_t
*ms
,
579 struct gmx_repl_ex
*re
,real
*ener
,real vol
,
583 real
*Epot
=NULL
,*Vol
=NULL
,*dvdl
=NULL
,*prob
;
584 real ediff
=0,delta
=0,dpV
=0,betaA
=0,betaB
=0;
585 gmx_bool
*bEx
,bPrint
;
588 fprintf(fplog
,"Replica exchange at step %d time %g\n",step
,time
);
593 snew(Epot
,re
->nrepl
);
595 Epot
[re
->repl
] = ener
[F_EPOT
];
597 gmx_sum_sim(re
->nrepl
,Epot
,ms
);
598 gmx_sum_sim(re
->nrepl
,Vol
,ms
);
601 snew(dvdl
,re
->nrepl
);
602 dvdl
[re
->repl
] = ener
[F_DVDL
];
603 gmx_sum_sim(re
->nrepl
,dvdl
,ms
);
608 snew(prob
,re
->nrepl
);
611 m
= (step
/ re
->nst
) % 2;
612 for(i
=1; i
<re
->nrepl
; i
++)
616 bPrint
= (re
->repl
==a
|| re
->repl
==b
);
622 /* Use equations from:
623 * Okabe et. al. Chem. Phys. Lett. 335 (2001) 435-439
625 ediff
= Epot
[b
] - Epot
[a
];
626 betaA
= 1.0/(re
->q
[a
]*BOLTZ
);
627 betaB
= 1.0/(re
->q
[b
]*BOLTZ
);
628 delta
= (betaA
- betaB
)*ediff
;
631 /* Here we exchange based on a linear extrapolation of dV/dlambda.
632 * We would like to have the real energies
633 * from foreign lambda calculations.
635 ediff
= (dvdl
[a
] - dvdl
[b
])*(re
->q
[b
] - re
->q
[a
]);
636 delta
= ediff
/(BOLTZ
*re
->temp
);
639 gmx_incons("Unknown replica exchange quantity");
643 fprintf(fplog
,"Repl %d <-> %d dE = %10.3e",a
,b
,delta
);
647 dpV
= (betaA
*re
->pres
[a
]-betaB
*re
->pres
[b
])*(Vol
[b
]-Vol
[a
])/PRESFAC
;
650 fprintf(fplog
," dpV = %10.3e d = %10.3e",dpV
,delta
+ dpV
);
671 prob
[i
] = exp(-delta
);
673 bEx
[i
] = (rando(&(re
->seed
)) < prob
[i
]);
675 re
->prob_sum
[i
] += prob
[i
];
682 else if (b
== re
->repl
)
695 print_ind(fplog
,"ex",re
->nrepl
,re
->ind
,bEx
);
696 print_prob(fplog
,"pr",re
->nrepl
,prob
);
710 static void write_debug_x(t_state
*state
)
716 for(i
=0; i
<state
->natoms
; i
+=10)
718 fprintf(debug
,"dx %5d %10.5f %10.5f %10.5f\n",i
,state
->x
[i
][XX
],state
->x
[i
][YY
],state
->x
[i
][ZZ
]);
723 gmx_bool
replica_exchange(FILE *fplog
,const t_commrec
*cr
,struct gmx_repl_ex
*re
,
724 t_state
*state
,real
*ener
,
725 t_state
*state_local
,
729 int exchange
=-1,shift
;
730 gmx_bool bExchanged
=FALSE
;
736 exchange
= get_replica_exchange(fplog
,ms
,re
,ener
,det(state
->box
),
738 bExchanged
= (exchange
>= 0);
744 MPI_Bcast(&bExchanged
,sizeof(gmx_bool
),MPI_BYTE
,MASTERRANK(cr
),
745 cr
->mpi_comm_mygroup
);
751 /* Exchange the states */
755 /* Collect the global state on the master node */
756 if (DOMAINDECOMP(cr
))
758 dd_collect_state(cr
->dd
,state_local
,state
);
762 pd_collect_state(cr
,state
);
768 /* Exchange the global states between the master nodes */
771 fprintf(debug
,"Exchanging %d with %d\n",ms
->sim
,exchange
);
773 exchange_state(ms
,exchange
,state
);
775 if (re
->type
== ereTEMP
)
777 scale_velocities(state
,sqrt(re
->q
[ms
->sim
]/re
->q
[exchange
]));
781 /* With domain decomposition the global state is distributed later */
782 if (!DOMAINDECOMP(cr
))
784 /* Copy the global state to the local state data structure */
785 copy_state_nonatomdata(state
,state_local
);
789 bcast_state(cr
,state
,FALSE
);
797 void print_replica_exchange_statistics(FILE *fplog
,struct gmx_repl_ex
*re
)
802 fprintf(fplog
,"\nReplica exchange statistics\n");
803 fprintf(fplog
,"Repl %d attempts, %d odd, %d even\n",
804 re
->nattempt
[0]+re
->nattempt
[1],re
->nattempt
[1],re
->nattempt
[0]);
806 snew(prob
,re
->nrepl
);
808 fprintf(fplog
,"Repl average probabilities:\n");
809 for(i
=1; i
<re
->nrepl
; i
++)
811 if (re
->nattempt
[i
%2] == 0)
817 prob
[i
] = re
->prob_sum
[i
]/re
->nattempt
[i
%2];
820 print_ind(fplog
,"",re
->nrepl
,re
->ind
,NULL
);
821 print_prob(fplog
,"",re
->nrepl
,prob
);
823 fprintf(fplog
,"Repl number of exchanges:\n");
824 print_ind(fplog
,"",re
->nrepl
,re
->ind
,NULL
);
825 print_count(fplog
,"",re
->nrepl
,re
->nexchange
);
827 fprintf(fplog
,"Repl average number of exchanges:\n");
828 for(i
=1; i
<re
->nrepl
; i
++)
830 if (re
->nattempt
[i
%2] == 0)
836 prob
[i
] = ((real
)re
->nexchange
[i
])/re
->nattempt
[i
%2];
839 print_ind(fplog
,"",re
->nrepl
,re
->ind
,NULL
);
840 print_prob(fplog
,"",re
->nrepl
,prob
);