void init_orires(FILE *fplog,const gmx_mtop_t *mtop, rvec xref[], const t_inputrec *ir, const gmx_multisim_t *ms,t_oriresdata *od, t_state *state) { int i,j,d,ex,nmol,nr,*nr_ex; double mtot; rvec com; gmx_mtop_ilistloop_t iloop; t_ilist *il; gmx_mtop_atomloop_all_t aloop; t_atom *atom; od->fc = ir->orires_fc; od->nex = 0; od->S = NULL; od->nr = gmx_mtop_ftype_count(mtop,F_ORIRES); if (od->nr == 0) { return; } nr_ex = NULL; iloop = gmx_mtop_ilistloop_init(mtop); while (gmx_mtop_ilistloop_next(iloop,&il,&nmol)) { for(i=0; i<il[F_ORIRES].nr; i+=3) { ex = mtop->ffparams.iparams[il[F_ORIRES].iatoms[i]].orires.ex; if (ex >= od->nex) { srenew(nr_ex,ex+1); for(j=od->nex; j<ex+1; j++) { nr_ex[j] = 0; } od->nex = ex+1; } nr_ex[ex]++; } } snew(od->S,od->nex); /* When not doing time averaging, the instaneous and time averaged data * are indentical and the pointers can point to the same memory. */ snew(od->Dinsl,od->nr); if (ms) { snew(od->Dins,od->nr); } else { od->Dins = od->Dinsl; } if (ir->orires_tau == 0) { od->Dtav = od->Dins; od->edt = 0.0; od->edt1 = 1.0; } else { snew(od->Dtav,od->nr); od->edt = exp(-ir->delta_t/ir->orires_tau); od->edt1 = 1.0 - od->edt; /* Extend the state with the orires history */ state->flags |= (1<<estORIRE_INITF); state->hist.orire_initf = 1; state->flags |= (1<<estORIRE_DTAV); state->hist.norire_Dtav = od->nr*5; snew(state->hist.orire_Dtav,state->hist.norire_Dtav); } snew(od->oinsl,od->nr); if (ms) { snew(od->oins,od->nr); } else { od->oins = od->oinsl; } if (ir->orires_tau == 0) { od->otav = od->oins; } else { snew(od->otav,od->nr); } snew(od->tmp,od->nex); snew(od->TMP,od->nex); for(ex=0; ex<od->nex; ex++) { snew(od->TMP[ex],5); for(i=0; i<5; i++) { snew(od->TMP[ex][i],5); } } od->nref = 0; for(i=0; i<mtop->natoms; i++) { if (ggrpnr(&mtop->groups,egcORFIT,i) == 0) { od->nref++; } } snew(od->mref,od->nref); snew(od->xref,od->nref); snew(od->xtmp,od->nref); snew(od->eig,od->nex*12); /* Determine the reference structure on the master node. * Copy it to the other nodes after checking multi compatibility, * so we are sure the subsystems match before copying. */ clear_rvec(com); mtot = 0.0; j = 0; aloop = gmx_mtop_atomloop_all_init(mtop); while(gmx_mtop_atomloop_all_next(aloop,&i,&atom)) { if (mtop->groups.grpnr[egcORFIT] == NULL || mtop->groups.grpnr[egcORFIT][i] == 0) { /* Not correct for free-energy with changing masses */ od->mref[j] = atom->m; if (ms==NULL || MASTERSIM(ms)) { copy_rvec(xref[i],od->xref[j]); for(d=0; d<DIM; d++) { com[d] += od->mref[j]*xref[i][d]; } } mtot += od->mref[j]; j++; } } svmul(1.0/mtot,com,com); if (ms==NULL || MASTERSIM(ms)) { for(j=0; j<od->nref; j++) { rvec_dec(od->xref[j],com); } } fprintf(fplog,"Found %d orientation experiments\n",od->nex); for(i=0; i<od->nex; i++) { fprintf(fplog," experiment %d has %d restraints\n",i+1,nr_ex[i]); } sfree(nr_ex); fprintf(fplog," the fit group consists of %d atoms and has total mass %g\n", od->nref,mtot); if (ms) { fprintf(fplog," the orientation restraints are ensemble averaged over %d systems\n",ms->nsim); check_multi_int(fplog,ms,od->nr, "the number of orientation restraints"); check_multi_int(fplog,ms,od->nref, "the number of fit atoms for orientation restraining"); check_multi_int(fplog,ms,ir->nsteps,"nsteps"); /* Copy the reference coordinates from the master to the other nodes */ gmx_sum_sim(DIM*od->nref,od->xref[0],ms); } please_cite(fplog,"Hess2003"); }
gmx_repl_ex_t init_replica_exchange(FILE *fplog, const gmx_multisim_t *ms, const t_state *state, const t_inputrec *ir, int nst, int nex, int init_seed) { real temp, pres; int i, j, k; struct gmx_repl_ex *re; gmx_bool bTemp; gmx_bool bLambda = FALSE; fprintf(fplog, "\nInitializing Replica Exchange\n"); if (ms == NULL || ms->nsim == 1) { gmx_fatal(FARGS, "Nothing to exchange with only one replica, maybe you forgot to set the -multi option of mdrun?"); } if (!EI_DYNAMICS(ir->eI)) { gmx_fatal(FARGS, "Replica exchange is only supported by dynamical simulations"); /* Note that PAR(cr) is defined by cr->nnodes > 1, which is * distinct from MULTISIM(cr). A multi-simulation only runs * with real MPI parallelism, but this does not imply PAR(cr) * is true! * * Since we are using a dynamical integrator, the only * decomposition is DD, so PAR(cr) and DOMAINDECOMP(cr) are * synonymous. The only way for cr->nnodes > 1 to be true is * if we are using DD. */ } snew(re, 1); re->repl = ms->sim; re->nrepl = ms->nsim; snew(re->q, ereENDSINGLE); fprintf(fplog, "Repl There are %d replicas:\n", re->nrepl); check_multi_int(fplog, ms, state->natoms, "the number of atoms", FALSE); check_multi_int(fplog, ms, ir->eI, "the integrator", FALSE); check_multi_int64(fplog, ms, ir->init_step+ir->nsteps, "init_step+nsteps", FALSE); check_multi_int64(fplog, ms, (ir->init_step+nst-1)/nst, "first exchange step: init_step/-replex", FALSE); check_multi_int(fplog, ms, ir->etc, "the temperature coupling", FALSE); check_multi_int(fplog, ms, ir->opts.ngtc, "the number of temperature coupling groups", FALSE); check_multi_int(fplog, ms, ir->epc, "the pressure coupling", FALSE); check_multi_int(fplog, ms, ir->efep, "free energy", FALSE); check_multi_int(fplog, ms, ir->fepvals->n_lambda, "number of lambda states", FALSE); re->temp = ir->opts.ref_t[0]; for (i = 1; (i < ir->opts.ngtc); i++) { if (ir->opts.ref_t[i] != re->temp) { fprintf(fplog, "\nWARNING: The temperatures of the different temperature coupling groups are not identical\n\n"); fprintf(stderr, "\nWARNING: The temperatures of the different temperature coupling groups are not identical\n\n"); } } re->type = -1; bTemp = repl_quantity(ms, re, ereTEMP, re->temp); if (ir->efep != efepNO) { bLambda = repl_quantity(ms, re, ereLAMBDA, (real)ir->fepvals->init_fep_state); } if (re->type == -1) /* nothing was assigned */ { gmx_fatal(FARGS, "The properties of the %d systems are all the same, there is nothing to exchange", re->nrepl); } if (bLambda && bTemp) { re->type = ereTL; } if (bTemp) { please_cite(fplog, "Sugita1999a"); if (ir->epc != epcNO) { re->bNPT = TRUE; fprintf(fplog, "Repl Using Constant Pressure REMD.\n"); please_cite(fplog, "Okabe2001a"); } if (ir->etc == etcBERENDSEN) { gmx_fatal(FARGS, "REMD with the %s thermostat does not produce correct potential energy distributions, consider using the %s thermostat instead", ETCOUPLTYPE(ir->etc), ETCOUPLTYPE(etcVRESCALE)); } } if (bLambda) { if (ir->fepvals->delta_lambda != 0) /* check this? */ { gmx_fatal(FARGS, "delta_lambda is not zero"); } } if (re->bNPT) { snew(re->pres, re->nrepl); if (ir->epct == epctSURFACETENSION) { pres = ir->ref_p[ZZ][ZZ]; } else { pres = 0; j = 0; for (i = 0; i < DIM; i++) { if (ir->compress[i][i] != 0) { pres += ir->ref_p[i][i]; j++; } } pres /= j; } re->pres[re->repl] = pres; gmx_sum_sim(re->nrepl, re->pres, ms); } /* Make an index for increasing replica order */ /* only makes sense if one or the other is varying, not both! if both are varying, we trust the order the person gave. */ snew(re->ind, re->nrepl); for (i = 0; i < re->nrepl; i++) { re->ind[i] = i; } if (re->type < ereENDSINGLE) { for (i = 0; i < re->nrepl; i++) { for (j = i+1; j < re->nrepl; j++) { if (re->q[re->type][re->ind[j]] < re->q[re->type][re->ind[i]]) { k = re->ind[i]; re->ind[i] = re->ind[j]; re->ind[j] = k; } else if (re->q[re->type][re->ind[j]] == re->q[re->type][re->ind[i]]) { gmx_fatal(FARGS, "Two replicas have identical %ss", erename[re->type]); } } } } /* keep track of all the swaps, starting with the initial placement. */ snew(re->allswaps, re->nrepl); for (i = 0; i < re->nrepl; i++) { re->allswaps[i] = re->ind[i]; } switch (re->type) { case ereTEMP: fprintf(fplog, "\nReplica exchange in temperature\n"); for (i = 0; i < re->nrepl; i++) { fprintf(fplog, " %5.1f", re->q[re->type][re->ind[i]]); } fprintf(fplog, "\n"); break; case ereLAMBDA: fprintf(fplog, "\nReplica exchange in lambda\n"); for (i = 0; i < re->nrepl; i++) { fprintf(fplog, " %3d", (int)re->q[re->type][re->ind[i]]); } fprintf(fplog, "\n"); break; case ereTL: fprintf(fplog, "\nReplica exchange in temperature and lambda state\n"); for (i = 0; i < re->nrepl; i++) { fprintf(fplog, " %5.1f", re->q[ereTEMP][re->ind[i]]); } fprintf(fplog, "\n"); for (i = 0; i < re->nrepl; i++) { fprintf(fplog, " %5d", (int)re->q[ereLAMBDA][re->ind[i]]); } fprintf(fplog, "\n"); break; default: gmx_incons("Unknown replica exchange quantity"); } if (re->bNPT) { fprintf(fplog, "\nRepl p"); for (i = 0; i < re->nrepl; i++) { fprintf(fplog, " %5.2f", re->pres[re->ind[i]]); } for (i = 0; i < re->nrepl; i++) { if ((i > 0) && (re->pres[re->ind[i]] < re->pres[re->ind[i-1]])) { fprintf(fplog, "\nWARNING: The reference pressures decrease with increasing temperatures\n\n"); fprintf(stderr, "\nWARNING: The reference pressures decrease with increasing temperatures\n\n"); } } } re->nst = nst; if (init_seed == -1) { if (MASTERSIM(ms)) { re->seed = (int)gmx_rng_make_seed(); } else { re->seed = 0; } gmx_sumi_sim(1, &(re->seed), ms); } else { re->seed = init_seed; } fprintf(fplog, "\nReplica exchange interval: %d\n", re->nst); fprintf(fplog, "\nReplica random seed: %d\n", re->seed); re->rng = gmx_rng_init(re->seed); re->nattempt[0] = 0; re->nattempt[1] = 0; snew(re->prob_sum, re->nrepl); snew(re->nexchange, re->nrepl); snew(re->nmoves, re->nrepl); for (i = 0; i < re->nrepl; i++) { snew(re->nmoves[i], re->nrepl); } fprintf(fplog, "Replica exchange information below: x=exchange, pr=probability\n"); /* generate space for the helper functions so we don't have to snew each time */ snew(re->destinations, re->nrepl); snew(re->incycle, re->nrepl); snew(re->tmpswap, re->nrepl); snew(re->cyclic, re->nrepl); snew(re->order, re->nrepl); for (i = 0; i < re->nrepl; i++) { snew(re->cyclic[i], re->nrepl); snew(re->order[i], re->nrepl); } /* allocate space for the functions storing the data for the replicas */ /* not all of these arrays needed in all cases, but they don't take up much space, since the max size is nrepl**2 */ snew(re->prob, re->nrepl); snew(re->bEx, re->nrepl); snew(re->beta, re->nrepl); snew(re->Vol, re->nrepl); snew(re->Epot, re->nrepl); snew(re->de, re->nrepl); for (i = 0; i < re->nrepl; i++) { snew(re->de[i], re->nrepl); } re->nex = nex; return re; }
gmx_repl_ex_t init_replica_exchange(FILE *fplog, const gmx_multisim_t *ms, const t_state *state, const t_inputrec *ir, int nst,int init_seed) { real temp,pres; int i,j,k; struct gmx_repl_ex *re; fprintf(fplog,"\nInitializing Replica Exchange\n"); if (ms == NULL || ms->nsim == 1) { gmx_fatal(FARGS,"Nothing to exchange with only one replica, maybe you forgot to set the -multi option of mdrun?"); } snew(re,1); re->repl = ms->sim; re->nrepl = ms->nsim; fprintf(fplog,"Repl There are %d replicas:\n",re->nrepl); check_multi_int(fplog,ms,state->natoms,"the number of atoms"); check_multi_int(fplog,ms,ir->eI,"the integrator"); check_multi_large_int(fplog,ms,ir->init_step+ir->nsteps,"init_step+nsteps"); check_multi_large_int(fplog,ms,(ir->init_step+nst-1)/nst, "first exchange step: init_step/-replex"); check_multi_int(fplog,ms,ir->etc,"the temperature coupling"); check_multi_int(fplog,ms,ir->opts.ngtc, "the number of temperature coupling groups"); check_multi_int(fplog,ms,ir->epc,"the pressure coupling"); check_multi_int(fplog,ms,ir->efep,"free energy"); re->temp = ir->opts.ref_t[0]; for(i=1; (i<ir->opts.ngtc); i++) { if (ir->opts.ref_t[i] != re->temp) { fprintf(fplog,"\nWARNING: The temperatures of the different temperature coupling groups are not identical\n\n"); fprintf(stderr,"\nWARNING: The temperatures of the different temperature coupling groups are not identical\n\n"); } } re->type = -1; for(i=0; i<ereNR; i++) { switch (i) { case ereTEMP: repl_quantity(fplog,ms,re,i,re->temp); break; case ereLAMBDA: if (ir->efep != efepNO) { repl_quantity(fplog,ms,re,i,ir->init_lambda); } break; default: gmx_incons("Unknown replica exchange quantity"); } } if (re->type == -1) { gmx_fatal(FARGS,"The properties of the %d systems are all the same, there is nothing to exchange",re->nrepl); } switch (re->type) { case ereTEMP: please_cite(fplog,"Hukushima96a"); if (ir->epc != epcNO) { re->bNPT = TRUE; fprintf(fplog,"Repl Using Constant Pressure REMD.\n"); please_cite(fplog,"Okabe2001a"); } if (ir->etc == etcBERENDSEN) { gmx_fatal(FARGS,"REMD with the %s thermostat does not produce correct potential energy distributions, consider using the %s thermostat instead", ETCOUPLTYPE(ir->etc),ETCOUPLTYPE(etcVRESCALE)); } break; case ereLAMBDA: if (ir->delta_lambda != 0) { gmx_fatal(FARGS,"delta_lambda is not zero"); } break; } if (re->bNPT) { snew(re->pres,re->nrepl); if (ir->epct == epctSURFACETENSION) { pres = ir->ref_p[ZZ][ZZ]; } else { pres = 0; j = 0; for(i=0; i<DIM; i++) { if (ir->compress[i][i] != 0) { pres += ir->ref_p[i][i]; j++; } } pres /= j; } re->pres[re->repl] = pres; gmx_sum_sim(re->nrepl,re->pres,ms); } snew(re->ind,re->nrepl); /* Make an index for increasing temperature order */ for(i=0; i<re->nrepl; i++) { re->ind[i] = i; } for(i=0; i<re->nrepl; i++) { for(j=i+1; j<re->nrepl; j++) { if (re->q[re->ind[j]] < re->q[re->ind[i]]) { k = re->ind[i]; re->ind[i] = re->ind[j]; re->ind[j] = k; } else if (re->q[re->ind[j]] == re->q[re->ind[i]]) { gmx_fatal(FARGS,"Two replicas have identical %ss",erename[re->type]); } } } fprintf(fplog,"Repl "); for(i=0; i<re->nrepl; i++) { fprintf(fplog," %3d ",re->ind[i]); } switch (re->type) { case ereTEMP: fprintf(fplog,"\nRepl T"); for(i=0; i<re->nrepl; i++) { fprintf(fplog," %5.1f",re->q[re->ind[i]]); } break; case ereLAMBDA: fprintf(fplog,"\nRepl l"); for(i=0; i<re->nrepl; i++) { fprintf(fplog," %5.3f",re->q[re->ind[i]]); } break; default: gmx_incons("Unknown replica exchange quantity"); } if (re->bNPT) { fprintf(fplog,"\nRepl p"); for(i=0; i<re->nrepl; i++) { fprintf(fplog," %5.2f",re->pres[re->ind[i]]); } for(i=0; i<re->nrepl; i++) { if ((i > 0) && (re->pres[re->ind[i]] < re->pres[re->ind[i-1]])) { gmx_fatal(FARGS,"The reference pressure decreases with increasing temperature"); } } } fprintf(fplog,"\nRepl "); re->nst = nst; if (init_seed == -1) { if (MASTERSIM(ms)) { re->seed = make_seed(); } else { re->seed = 0; } gmx_sumi_sim(1,&(re->seed),ms); } else { re->seed = init_seed; } fprintf(fplog,"\nRepl exchange interval: %d\n",re->nst); fprintf(fplog,"\nRepl random seed: %d\n",re->seed); re->nattempt[0] = 0; re->nattempt[1] = 0; snew(re->prob_sum,re->nrepl); snew(re->nexchange,re->nrepl); fprintf(fplog,"Repl below: x=exchange, pr=probability\n"); return re; }