void mdoutf_write_to_trajectory_files(FILE *fplog, t_commrec *cr, gmx_mdoutf_t of, int mdof_flags, gmx_mtop_t *top_global, gmx_int64_t step, double t, t_state *state_local, t_state *state_global, rvec *f_local, rvec *f_global) { rvec *local_v; rvec *global_v; /* MRS -- defining these variables is to manage the difference * between half step and full step velocities, but there must be a better way . . . */ local_v = state_local->v; global_v = state_global->v; if (DOMAINDECOMP(cr)) { if (mdof_flags & MDOF_CPT) { dd_collect_state(cr->dd, state_local, state_global); } else { if (mdof_flags & (MDOF_X | MDOF_X_COMPRESSED)) { dd_collect_vec(cr->dd, state_local, state_local->x, state_global->x); } if (mdof_flags & MDOF_V) { dd_collect_vec(cr->dd, state_local, local_v, global_v); } } if (mdof_flags & MDOF_F) { dd_collect_vec(cr->dd, state_local, f_local, f_global); } } else { if (mdof_flags & MDOF_CPT) { /* All pointers in state_local are equal to state_global, * but we need to copy the non-pointer entries. */ state_global->lambda = state_local->lambda; state_global->veta = state_local->veta; state_global->vol0 = state_local->vol0; copy_mat(state_local->box, state_global->box); copy_mat(state_local->boxv, state_global->boxv); copy_mat(state_local->svir_prev, state_global->svir_prev); copy_mat(state_local->fvir_prev, state_global->fvir_prev); copy_mat(state_local->pres_prev, state_global->pres_prev); } } if (MASTER(cr)) { if (mdof_flags & MDOF_CPT) { fflush_tng(of->tng); fflush_tng(of->tng_low_prec); write_checkpoint(of->fn_cpt, of->bKeepAndNumCPT, fplog, cr, of->eIntegrator, of->simulation_part, of->bExpanded, of->elamstats, step, t, state_global); } if (mdof_flags & (MDOF_X | MDOF_V | MDOF_F)) { if (of->fp_trn) { gmx_trr_write_frame(of->fp_trn, step, t, state_local->lambda[efptFEP], state_local->box, top_global->natoms, (mdof_flags & MDOF_X) ? state_global->x : NULL, (mdof_flags & MDOF_V) ? global_v : NULL, (mdof_flags & MDOF_F) ? f_global : NULL); if (gmx_fio_flush(of->fp_trn) != 0) { gmx_file("Cannot write trajectory; maybe you are out of disk space?"); } } gmx_fwrite_tng(of->tng, FALSE, step, t, state_local->lambda[efptFEP], state_local->box, top_global->natoms, (mdof_flags & MDOF_X) ? state_global->x : NULL, (mdof_flags & MDOF_V) ? global_v : NULL, (mdof_flags & MDOF_F) ? f_global : NULL); } if (mdof_flags & MDOF_X_COMPRESSED) { rvec *xxtc = NULL; if (of->natoms_x_compressed == of->natoms_global) { /* We are writing the positions of all of the atoms to the compressed output */ xxtc = state_global->x; } else { /* We are writing the positions of only a subset of the atoms to the compressed output, so we have to make a copy of the subset of coordinates. */ int i, j; snew(xxtc, of->natoms_x_compressed); for (i = 0, j = 0; (i < of->natoms_global); i++) { if (ggrpnr(of->groups, egcCompressedX, i) == 0) { copy_rvec(state_global->x[i], xxtc[j++]); } } } if (write_xtc(of->fp_xtc, of->natoms_x_compressed, step, t, state_local->box, xxtc, of->x_compression_precision) == 0) { gmx_fatal(FARGS, "XTC error - maybe you are out of disk space?"); } gmx_fwrite_tng(of->tng_low_prec, TRUE, step, t, state_local->lambda[efptFEP], state_local->box, of->natoms_x_compressed, xxtc, NULL, NULL); if (of->natoms_x_compressed != of->natoms_global) { sfree(xxtc); } } } }
gmx_bool replica_exchange(FILE *fplog, const t_commrec *cr, struct gmx_repl_ex *re, t_state *state, gmx_enerdata_t *enerd, t_state *state_local, gmx_int64_t step, real time) { int i, j; int replica_id = 0; int exchange_partner; int maxswap = 0; /* Number of rounds of exchanges needed to deal with any multiple * exchanges. */ /* Where each replica ends up after the exchange attempt(s). */ /* The order in which multiple exchanges will occur. */ gmx_bool bThisReplicaExchanged = FALSE; if (MASTER(cr)) { replica_id = re->repl; test_for_replica_exchange(fplog, cr->ms, re, enerd, det(state_local->box), step, time); prepare_to_do_exchange(fplog, re->destinations, replica_id, re->nrepl, &maxswap, re->order, re->cyclic, re->incycle, &bThisReplicaExchanged); } /* Do intra-simulation broadcast so all processors belonging to * each simulation know whether they need to participate in * collecting the state. Otherwise, they might as well get on with * the next thing to do. */ if (DOMAINDECOMP(cr)) { #ifdef GMX_MPI MPI_Bcast(&bThisReplicaExchanged, sizeof(gmx_bool), MPI_BYTE, MASTERRANK(cr), cr->mpi_comm_mygroup); #endif } if (bThisReplicaExchanged) { /* Exchange the states */ /* Collect the global state on the master node */ if (DOMAINDECOMP(cr)) { dd_collect_state(cr->dd, state_local, state); } else { copy_state_nonatomdata(state_local, state); } if (MASTER(cr)) { /* There will be only one swap cycle with standard replica * exchange, but there may be multiple swap cycles if we * allow multiple swaps. */ for (j = 0; j < maxswap; j++) { exchange_partner = re->order[replica_id][j]; if (exchange_partner != replica_id) { /* Exchange the global states between the master nodes */ if (debug) { fprintf(debug, "Exchanging %d with %d\n", replica_id, exchange_partner); } exchange_state(cr->ms, exchange_partner, state); } } /* For temperature-type replica exchange, we need to scale * the velocities. */ if (re->type == ereTEMP || re->type == ereTL) { scale_velocities(state, sqrt(re->q[ereTEMP][replica_id]/re->q[ereTEMP][re->destinations[replica_id]])); } } /* With domain decomposition the global state is distributed later */ if (!DOMAINDECOMP(cr)) { /* Copy the global state to the local state data structure */ copy_state_nonatomdata(state, state_local); } } return bThisReplicaExchanged; }
gmx_bool replica_exchange(FILE *fplog,const t_commrec *cr,struct gmx_repl_ex *re, t_state *state,real *ener, t_state *state_local, int step,real time) { gmx_multisim_t *ms; int exchange=-1,shift; gmx_bool bExchanged=FALSE; ms = cr->ms; if (MASTER(cr)) { exchange = get_replica_exchange(fplog,ms,re,ener,det(state->box), step,time); bExchanged = (exchange >= 0); } if (PAR(cr)) { #ifdef GMX_MPI MPI_Bcast(&bExchanged,sizeof(gmx_bool),MPI_BYTE,MASTERRANK(cr), cr->mpi_comm_mygroup); #endif } if (bExchanged) { /* Exchange the states */ if (PAR(cr)) { /* Collect the global state on the master node */ if (DOMAINDECOMP(cr)) { dd_collect_state(cr->dd,state_local,state); } else { pd_collect_state(cr,state); } } if (MASTER(cr)) { /* Exchange the global states between the master nodes */ if (debug) { fprintf(debug,"Exchanging %d with %d\n",ms->sim,exchange); } exchange_state(ms,exchange,state); if (re->type == ereTEMP) { scale_velocities(state,sqrt(re->q[ms->sim]/re->q[exchange])); } } /* With domain decomposition the global state is distributed later */ if (!DOMAINDECOMP(cr)) { /* Copy the global state to the local state data structure */ copy_state_nonatomdata(state,state_local); if (PAR(cr)) { bcast_state(cr,state,FALSE); } } } return bExchanged; }