t_mdebin *init_mdebin(ener_file_t fp_ene, const gmx_mtop_t *mtop, const t_inputrec *ir, FILE *fp_dhdl) { const char *ener_nm[F_NRE]; static const char *vir_nm[] = { "Vir-XX", "Vir-XY", "Vir-XZ", "Vir-YX", "Vir-YY", "Vir-YZ", "Vir-ZX", "Vir-ZY", "Vir-ZZ" }; static const char *sv_nm[] = { "ShakeVir-XX", "ShakeVir-XY", "ShakeVir-XZ", "ShakeVir-YX", "ShakeVir-YY", "ShakeVir-YZ", "ShakeVir-ZX", "ShakeVir-ZY", "ShakeVir-ZZ" }; static const char *fv_nm[] = { "ForceVir-XX", "ForceVir-XY", "ForceVir-XZ", "ForceVir-YX", "ForceVir-YY", "ForceVir-YZ", "ForceVir-ZX", "ForceVir-ZY", "ForceVir-ZZ" }; static const char *pres_nm[] = { "Pres-XX","Pres-XY","Pres-XZ", "Pres-YX","Pres-YY","Pres-YZ", "Pres-ZX","Pres-ZY","Pres-ZZ" }; static const char *surft_nm[] = { "#Surf*SurfTen" }; static const char *mu_nm[] = { "Mu-X", "Mu-Y", "Mu-Z" }; static const char *vcos_nm[] = { "2CosZ*Vel-X" }; static const char *visc_nm[] = { "1/Viscosity" }; static const char *baro_nm[] = { "Barostat" }; char **grpnms; const gmx_groups_t *groups; char **gnm; char buf[256]; const char *bufi; t_mdebin *md; int i,j,ni,nj,n,nh,k,kk,ncon,nset; gmx_bool bBHAM,bNoseHoover,b14; snew(md,1); if (EI_DYNAMICS(ir->eI)) { md->delta_t = ir->delta_t; } else { md->delta_t = 0; } groups = &mtop->groups; bBHAM = (mtop->ffparams.functype[0] == F_BHAM); b14 = (gmx_mtop_ftype_count(mtop,F_LJ14) > 0 || gmx_mtop_ftype_count(mtop,F_LJC14_Q) > 0); ncon = gmx_mtop_ftype_count(mtop,F_CONSTR); nset = gmx_mtop_ftype_count(mtop,F_SETTLE); md->bConstr = (ncon > 0 || nset > 0); md->bConstrVir = FALSE; if (md->bConstr) { if (ncon > 0 && ir->eConstrAlg == econtLINCS) { if (ir->eI == eiSD2) md->nCrmsd = 2; else md->nCrmsd = 1; } md->bConstrVir = (getenv("GMX_CONSTRAINTVIR") != NULL); } else { md->nCrmsd = 0; } /* Energy monitoring */ for(i=0;i<egNR;i++) { md->bEInd[i]=FALSE; } #ifndef GMX_OPENMM for(i=0; i<F_NRE; i++) { md->bEner[i] = FALSE; if (i == F_LJ) md->bEner[i] = !bBHAM; else if (i == F_BHAM) md->bEner[i] = bBHAM; else if (i == F_EQM) md->bEner[i] = ir->bQMMM; else if (i == F_COUL_LR) md->bEner[i] = (ir->rcoulomb > ir->rlist); else if (i == F_LJ_LR) md->bEner[i] = (!bBHAM && ir->rvdw > ir->rlist); else if (i == F_BHAM_LR) md->bEner[i] = (bBHAM && ir->rvdw > ir->rlist); else if (i == F_RF_EXCL) md->bEner[i] = (EEL_RF(ir->coulombtype) && ir->coulombtype != eelRF_NEC); else if (i == F_COUL_RECIP) md->bEner[i] = EEL_FULL(ir->coulombtype); else if (i == F_LJ14) md->bEner[i] = b14; else if (i == F_COUL14) md->bEner[i] = b14; else if (i == F_LJC14_Q || i == F_LJC_PAIRS_NB) md->bEner[i] = FALSE; else if ((i == F_DVDL) || (i == F_DKDL)) md->bEner[i] = (ir->efep != efepNO); else if (i == F_DHDL_CON) md->bEner[i] = (ir->efep != efepNO && md->bConstr); else if ((interaction_function[i].flags & IF_VSITE) || (i == F_CONSTR) || (i == F_CONSTRNC) || (i == F_SETTLE)) md->bEner[i] = FALSE; else if ((i == F_COUL_SR) || (i == F_EPOT) || (i == F_PRES) || (i==F_EQM)) md->bEner[i] = TRUE; else if ((i == F_GBPOL) && ir->implicit_solvent==eisGBSA) md->bEner[i] = TRUE; else if ((i == F_NPSOLVATION) && ir->implicit_solvent==eisGBSA && (ir->sa_algorithm != esaNO)) md->bEner[i] = TRUE; else if ((i == F_GB12) || (i == F_GB13) || (i == F_GB14)) md->bEner[i] = FALSE; else if ((i == F_ETOT) || (i == F_EKIN) || (i == F_TEMP)) md->bEner[i] = EI_DYNAMICS(ir->eI); else if (i==F_VTEMP) md->bEner[i] = (EI_DYNAMICS(ir->eI) && getenv("GMX_VIRIAL_TEMPERATURE")); else if (i == F_DISPCORR || i == F_PDISPCORR) md->bEner[i] = (ir->eDispCorr != edispcNO); else if (i == F_DISRESVIOL) md->bEner[i] = (gmx_mtop_ftype_count(mtop,F_DISRES) > 0); else if (i == F_ORIRESDEV) md->bEner[i] = (gmx_mtop_ftype_count(mtop,F_ORIRES) > 0); else if (i == F_CONNBONDS) md->bEner[i] = FALSE; else if (i == F_COM_PULL) md->bEner[i] = (ir->ePull == epullUMBRELLA || ir->ePull == epullCONST_F); else if (i == F_ECONSERVED) md->bEner[i] = ((ir->etc == etcNOSEHOOVER || ir->etc == etcVRESCALE) && (ir->epc == epcNO || ir->epc==epcMTTK)); else md->bEner[i] = (gmx_mtop_ftype_count(mtop,i) > 0); } #else /* OpenMM always produces only the following 4 energy terms */ md->bEner[F_EPOT] = TRUE; md->bEner[F_EKIN] = TRUE; md->bEner[F_ETOT] = TRUE; md->bEner[F_TEMP] = TRUE; #endif md->f_nre=0; for(i=0; i<F_NRE; i++) { if (md->bEner[i]) { /* FIXME: The constness should not be cast away */ /*ener_nm[f_nre]=(char *)interaction_function[i].longname;*/ ener_nm[md->f_nre]=interaction_function[i].longname; md->f_nre++; } } md->epc = ir->epc; for (i=0;i<DIM;i++) { for (j=0;j<DIM;j++) { md->ref_p[i][j] = ir->ref_p[i][j]; } } md->bTricl = TRICLINIC(ir->compress) || TRICLINIC(ir->deform); md->bDynBox = DYNAMIC_BOX(*ir); md->etc = ir->etc; md->bNHC_trotter = IR_NVT_TROTTER(ir); md->bMTTK = IR_NPT_TROTTER(ir); md->ebin = mk_ebin(); /* Pass NULL for unit to let get_ebin_space determine the units * for interaction_function[i].longname */ md->ie = get_ebin_space(md->ebin,md->f_nre,ener_nm,NULL); if (md->nCrmsd) { /* This should be called directly after the call for md->ie, * such that md->iconrmsd follows directly in the list. */ md->iconrmsd = get_ebin_space(md->ebin,md->nCrmsd,conrmsd_nm,""); } if (md->bDynBox) { md->ib = get_ebin_space(md->ebin, md->bTricl ? NTRICLBOXS : NBOXS, md->bTricl ? tricl_boxs_nm : boxs_nm, unit_length); md->ivol = get_ebin_space(md->ebin, 1, vol_nm, unit_volume); md->idens = get_ebin_space(md->ebin, 1, dens_nm, unit_density_SI); md->ipv = get_ebin_space(md->ebin, 1, pv_nm, unit_energy); md->ienthalpy = get_ebin_space(md->ebin, 1, enthalpy_nm, unit_energy); } if (md->bConstrVir) { md->isvir = get_ebin_space(md->ebin,asize(sv_nm),sv_nm,unit_energy); md->ifvir = get_ebin_space(md->ebin,asize(fv_nm),fv_nm,unit_energy); } md->ivir = get_ebin_space(md->ebin,asize(vir_nm),vir_nm,unit_energy); md->ipres = get_ebin_space(md->ebin,asize(pres_nm),pres_nm,unit_pres_bar); md->isurft = get_ebin_space(md->ebin,asize(surft_nm),surft_nm, unit_surft_bar); if (md->epc == epcPARRINELLORAHMAN || md->epc == epcMTTK) { md->ipc = get_ebin_space(md->ebin,md->bTricl ? 6 : 3, boxvel_nm,unit_vel); } md->imu = get_ebin_space(md->ebin,asize(mu_nm),mu_nm,unit_dipole_D); if (ir->cos_accel != 0) { md->ivcos = get_ebin_space(md->ebin,asize(vcos_nm),vcos_nm,unit_vel); md->ivisc = get_ebin_space(md->ebin,asize(visc_nm),visc_nm, unit_invvisc_SI); } /* Energy monitoring */ for(i=0;i<egNR;i++) { md->bEInd[i] = FALSE; } md->bEInd[egCOULSR] = TRUE; md->bEInd[egLJSR ] = TRUE; if (ir->rcoulomb > ir->rlist) { md->bEInd[egCOULLR] = TRUE; } if (!bBHAM) { if (ir->rvdw > ir->rlist) { md->bEInd[egLJLR] = TRUE; } } else { md->bEInd[egLJSR] = FALSE; md->bEInd[egBHAMSR] = TRUE; if (ir->rvdw > ir->rlist) { md->bEInd[egBHAMLR] = TRUE; } } if (b14) { md->bEInd[egLJ14] = TRUE; md->bEInd[egCOUL14] = TRUE; } md->nEc=0; for(i=0; (i<egNR); i++) { if (md->bEInd[i]) { md->nEc++; } } n=groups->grps[egcENER].nr; md->nEg=n; md->nE=(n*(n+1))/2; snew(md->igrp,md->nE); if (md->nE > 1) { n=0; snew(gnm,md->nEc); for(k=0; (k<md->nEc); k++) { snew(gnm[k],STRLEN); } for(i=0; (i<groups->grps[egcENER].nr); i++) { ni=groups->grps[egcENER].nm_ind[i]; for(j=i; (j<groups->grps[egcENER].nr); j++) { nj=groups->grps[egcENER].nm_ind[j]; for(k=kk=0; (k<egNR); k++) { if (md->bEInd[k]) { sprintf(gnm[kk],"%s:%s-%s",egrp_nm[k], *(groups->grpname[ni]),*(groups->grpname[nj])); kk++; } } md->igrp[n]=get_ebin_space(md->ebin,md->nEc, (const char **)gnm,unit_energy); n++; } } for(k=0; (k<md->nEc); k++) { sfree(gnm[k]); } sfree(gnm); if (n != md->nE) { gmx_incons("Number of energy terms wrong"); } } md->nTC=groups->grps[egcTC].nr; md->nNHC = ir->opts.nhchainlength; /* shorthand for number of NH chains */ if (md->bMTTK) { md->nTCP = 1; /* assume only one possible coupling system for barostat for now */ } else { md->nTCP = 0; } if (md->etc == etcNOSEHOOVER) { if (md->bNHC_trotter) { md->mde_n = 2*md->nNHC*md->nTC; } else { md->mde_n = 2*md->nTC; } if (md->epc == epcMTTK) { md->mdeb_n = 2*md->nNHC*md->nTCP; } } else { md->mde_n = md->nTC; md->mdeb_n = 0; } snew(md->tmp_r,md->mde_n); snew(md->tmp_v,md->mde_n); snew(md->grpnms,md->mde_n); grpnms = md->grpnms; for(i=0; (i<md->nTC); i++) { ni=groups->grps[egcTC].nm_ind[i]; sprintf(buf,"T-%s",*(groups->grpname[ni])); grpnms[i]=strdup(buf); } md->itemp=get_ebin_space(md->ebin,md->nTC,(const char **)grpnms, unit_temp_K); bNoseHoover = (getenv("GMX_NOSEHOOVER_CHAINS") != NULL); /* whether to print Nose-Hoover chains */ if (md->etc == etcNOSEHOOVER) { if (bNoseHoover) { if (md->bNHC_trotter) { for(i=0; (i<md->nTC); i++) { ni=groups->grps[egcTC].nm_ind[i]; bufi = *(groups->grpname[ni]); for(j=0; (j<md->nNHC); j++) { sprintf(buf,"Xi-%d-%s",j,bufi); grpnms[2*(i*md->nNHC+j)]=strdup(buf); sprintf(buf,"vXi-%d-%s",j,bufi); grpnms[2*(i*md->nNHC+j)+1]=strdup(buf); } } md->itc=get_ebin_space(md->ebin,md->mde_n, (const char **)grpnms,unit_invtime); if (md->bMTTK) { for(i=0; (i<md->nTCP); i++) { bufi = baro_nm[0]; /* All barostat DOF's together for now. */ for(j=0; (j<md->nNHC); j++) { sprintf(buf,"Xi-%d-%s",j,bufi); grpnms[2*(i*md->nNHC+j)]=strdup(buf); sprintf(buf,"vXi-%d-%s",j,bufi); grpnms[2*(i*md->nNHC+j)+1]=strdup(buf); } } md->itcb=get_ebin_space(md->ebin,md->mdeb_n, (const char **)grpnms,unit_invtime); } } else { for(i=0; (i<md->nTC); i++) { ni=groups->grps[egcTC].nm_ind[i]; bufi = *(groups->grpname[ni]); sprintf(buf,"Xi-%s",bufi); grpnms[2*i]=strdup(buf); sprintf(buf,"vXi-%s",bufi); grpnms[2*i+1]=strdup(buf); } md->itc=get_ebin_space(md->ebin,md->mde_n, (const char **)grpnms,unit_invtime); } } } else if (md->etc == etcBERENDSEN || md->etc == etcYES || md->etc == etcVRESCALE) { for(i=0; (i<md->nTC); i++) { ni=groups->grps[egcTC].nm_ind[i]; sprintf(buf,"Lamb-%s",*(groups->grpname[ni])); grpnms[i]=strdup(buf); } md->itc=get_ebin_space(md->ebin,md->mde_n,(const char **)grpnms,""); } sfree(grpnms); md->nU=groups->grps[egcACC].nr; if (md->nU > 1) { snew(grpnms,3*md->nU); for(i=0; (i<md->nU); i++) { ni=groups->grps[egcACC].nm_ind[i]; sprintf(buf,"Ux-%s",*(groups->grpname[ni])); grpnms[3*i+XX]=strdup(buf); sprintf(buf,"Uy-%s",*(groups->grpname[ni])); grpnms[3*i+YY]=strdup(buf); sprintf(buf,"Uz-%s",*(groups->grpname[ni])); grpnms[3*i+ZZ]=strdup(buf); } md->iu=get_ebin_space(md->ebin,3*md->nU,(const char **)grpnms,unit_vel); sfree(grpnms); } if ( fp_ene ) { do_enxnms(fp_ene,&md->ebin->nener,&md->ebin->enm); } md->print_grpnms=NULL; /* check whether we're going to write dh histograms */ md->dhc=NULL; if (ir->separate_dhdl_file == sepdhdlfileNO ) { int i; snew(md->dhc, 1); mde_delta_h_coll_init(md->dhc, ir); md->fp_dhdl = NULL; } else { md->fp_dhdl = fp_dhdl; } md->dhdl_derivatives = (ir->dhdl_derivatives==dhdlderivativesYES); return md; }
extern int ExpandedEnsembleDynamics(FILE *log, t_inputrec *ir, gmx_enerdata_t *enerd, t_state *state, t_extmass *MassQ, int fep_state, df_history_t *dfhist, gmx_int64_t step, rvec *v, t_mdatoms *mdatoms) /* Note that the state variable is only needed for simulated tempering, not Hamiltonian expanded ensemble. May be able to remove it after integrator refactoring. */ { real *pfep_lamee, *scaled_lamee, *weighted_lamee; double *p_k; int i, nlim, lamnew, totalsamples; real oneovert, maxscaled = 0, maxweighted = 0; t_expanded *expand; t_simtemp *simtemp; double *temperature_lambdas; gmx_bool bIfReset, bSwitchtoOneOverT, bDoneEquilibrating = FALSE; expand = ir->expandedvals; simtemp = ir->simtempvals; nlim = ir->fepvals->n_lambda; snew(scaled_lamee, nlim); snew(weighted_lamee, nlim); snew(pfep_lamee, nlim); snew(p_k, nlim); /* update the count at the current lambda*/ dfhist->n_at_lam[fep_state]++; /* need to calculate the PV term somewhere, but not needed here? Not until there's a lambda state that's pressure controlled.*/ /* pVTerm = 0; where does this PV term go? for (i=0;i<nlim;i++) { fep_lamee[i] += pVTerm; } */ /* determine the minimum value to avoid overflow. Probably a better way to do this */ /* we don't need to include the pressure term, since the volume is the same between the two. is there some term we are neglecting, however? */ if (ir->efep != efepNO) { for (i = 0; i < nlim; i++) { if (ir->bSimTemp) { /* Note -- this assumes no mass changes, since kinetic energy is not added . . . */ scaled_lamee[i] = (enerd->enerpart_lambda[i+1]-enerd->enerpart_lambda[0])/(simtemp->temperatures[i]*BOLTZ) + enerd->term[F_EPOT]*(1.0/(simtemp->temperatures[i])- 1.0/(simtemp->temperatures[fep_state]))/BOLTZ; } else { scaled_lamee[i] = (enerd->enerpart_lambda[i+1]-enerd->enerpart_lambda[0])/(expand->mc_temp*BOLTZ); /* mc_temp is currently set to the system reft unless otherwise defined */ } /* save these energies for printing, so they don't get overwritten by the next step */ /* they aren't overwritten in the non-free energy case, but we always print with these for simplicity */ } } else { if (ir->bSimTemp) { for (i = 0; i < nlim; i++) { scaled_lamee[i] = enerd->term[F_EPOT]*(1.0/simtemp->temperatures[i] - 1.0/simtemp->temperatures[fep_state])/BOLTZ; } } } for (i = 0; i < nlim; i++) { pfep_lamee[i] = scaled_lamee[i]; weighted_lamee[i] = dfhist->sum_weights[i] - scaled_lamee[i]; if (i == 0) { maxscaled = scaled_lamee[i]; maxweighted = weighted_lamee[i]; } else { if (scaled_lamee[i] > maxscaled) { maxscaled = scaled_lamee[i]; } if (weighted_lamee[i] > maxweighted) { maxweighted = weighted_lamee[i]; } } } for (i = 0; i < nlim; i++) { scaled_lamee[i] -= maxscaled; weighted_lamee[i] -= maxweighted; } /* update weights - we decide whether or not to actually do this inside */ bDoneEquilibrating = UpdateWeights(nlim, expand, dfhist, fep_state, scaled_lamee, weighted_lamee, step); if (bDoneEquilibrating) { if (log) { fprintf(log, "\nStep %d: Weights have equilibrated, using criteria: %s\n", (int)step, elmceq_names[expand->elmceq]); } } lamnew = ChooseNewLambda(nlim, expand, dfhist, fep_state, weighted_lamee, p_k, ir->expandedvals->lmc_seed, step); /* if using simulated tempering, we need to adjust the temperatures */ if (ir->bSimTemp && (lamnew != fep_state)) /* only need to change the temperatures if we change the state */ { int i, j, n, d; real *buf_ngtc; real told; int nstart, nend, gt; snew(buf_ngtc, ir->opts.ngtc); for (i = 0; i < ir->opts.ngtc; i++) { if (ir->opts.ref_t[i] > 0) { told = ir->opts.ref_t[i]; ir->opts.ref_t[i] = simtemp->temperatures[lamnew]; buf_ngtc[i] = sqrt(ir->opts.ref_t[i]/told); /* using the buffer as temperature scaling */ } } /* we don't need to manipulate the ekind information, as it isn't due to be reset until the next step anyway */ nstart = 0; nend = mdatoms->homenr; for (n = nstart; n < nend; n++) { gt = 0; if (mdatoms->cTC) { gt = mdatoms->cTC[n]; } for (d = 0; d < DIM; d++) { v[n][d] *= buf_ngtc[gt]; } } if (IR_NPT_TROTTER(ir) || IR_NPH_TROTTER(ir) || IR_NVT_TROTTER(ir)) { /* we need to recalculate the masses if the temperature has changed */ init_npt_masses(ir, state, MassQ, FALSE); for (i = 0; i < state->nnhpres; i++) { for (j = 0; j < ir->opts.nhchainlength; j++) { state->nhpres_vxi[i+j] *= buf_ngtc[i]; } } for (i = 0; i < ir->opts.ngtc; i++) { for (j = 0; j < ir->opts.nhchainlength; j++) { state->nosehoover_vxi[i+j] *= buf_ngtc[i]; } } } sfree(buf_ngtc); } /* now check on the Wang-Landau updating critera */ if (EWL(expand->elamstats)) { bSwitchtoOneOverT = FALSE; if (expand->bWLoneovert) { totalsamples = 0; for (i = 0; i < nlim; i++) { totalsamples += dfhist->n_at_lam[i]; } oneovert = (1.0*nlim)/totalsamples; /* oneovert has decreasd by a bit since last time, so we actually make sure its within one of this number */ /* switch to 1/t incrementing when wl_delta has decreased at least once, and wl_delta is now less than 1/t */ if ((dfhist->wl_delta <= ((totalsamples)/(totalsamples-1.00001))*oneovert) && (dfhist->wl_delta < expand->init_wl_delta)) { bSwitchtoOneOverT = TRUE; } } if (bSwitchtoOneOverT) { dfhist->wl_delta = oneovert; /* now we reduce by this each time, instead of only at flatness */ } else { bIfReset = CheckHistogramRatios(nlim, dfhist->wl_histo, expand->wl_ratio); if (bIfReset) { for (i = 0; i < nlim; i++) { dfhist->wl_histo[i] = 0; } dfhist->wl_delta *= expand->wl_scale; if (log) { fprintf(log, "\nStep %d: weights are now:", (int)step); for (i = 0; i < nlim; i++) { fprintf(log, " %.5f", dfhist->sum_weights[i]); } fprintf(log, "\n"); } } } } sfree(pfep_lamee); sfree(scaled_lamee); sfree(weighted_lamee); sfree(p_k); return lamnew; }
real NPT_energy(t_inputrec *ir, t_state *state, t_extmass *MassQ) { int i,j,nd,ndj,bmass,qmass,ngtcall; real ener_npt,reft,eta,kT,tau; double *ivxi, *ixi; double *iQinv; real vol,dbaro,W,Q; int nh = state->nhchainlength; ener_npt = 0; /* now we compute the contribution of the pressure to the conserved quantity*/ if (ir->epc==epcMTTK) { /* find the volume, and the kinetic energy of the volume */ switch (ir->epct) { case epctISOTROPIC: /* contribution from the pressure momenenta */ ener_npt += 0.5*sqr(state->veta)/MassQ->Winv; /* contribution from the PV term */ vol = det(state->box); ener_npt += vol*trace(ir->ref_p)/(DIM*PRESFAC); break; case epctANISOTROPIC: break; case epctSURFACETENSION: break; case epctSEMIISOTROPIC: break; default: break; } } if (IR_NPT_TROTTER(ir)) { /* add the energy from the barostat thermostat chain */ for (i=0;i<state->nnhpres;i++) { /* note -- assumes only one degree of freedom that is thermostatted in barostat */ ivxi = &state->nhpres_vxi[i*nh]; ixi = &state->nhpres_xi[i*nh]; iQinv = &(MassQ->QPinv[i*nh]); reft = max(ir->opts.ref_t[0],0); /* using 'System' temperature */ kT = BOLTZ * reft; for (j=0;j<nh;j++) { if (iQinv[j] > 0) { ener_npt += 0.5*sqr(ivxi[j])/iQinv[j]; /* contribution from the thermal variable of the NH chain */ ener_npt += ixi[j]*kT; } if (debug) { fprintf(debug,"P-T-group: %10d Chain %4d ThermV: %15.8f ThermX: %15.8f",i,j,ivxi[j],ixi[j]); } } } } if (ir->etc) { for(i=0; i<ir->opts.ngtc; i++) { ixi = &state->nosehoover_xi[i*nh]; ivxi = &state->nosehoover_vxi[i*nh]; iQinv = &(MassQ->Qinv[i*nh]); nd = ir->opts.nrdf[i]; reft = max(ir->opts.ref_t[i],0); kT = BOLTZ * reft; if (nd > 0) { if (IR_NVT_TROTTER(ir)) { /* contribution from the thermal momenta of the NH chain */ for (j=0;j<nh;j++) { if (iQinv[j] > 0) { ener_npt += 0.5*sqr(ivxi[j])/iQinv[j]; /* contribution from the thermal variable of the NH chain */ if (j==0) { ndj = nd; } else { ndj = 1; } ener_npt += ndj*ixi[j]*kT; } } } else /* Other non Trotter temperature NH control -- no chains yet. */ { ener_npt += 0.5*BOLTZ*nd*sqr(ivxi[0])/iQinv[0]; ener_npt += nd*ixi[0]*kT; } } } } return ener_npt; }
void get_enx_state(const char *fn, real t, gmx_groups_t *groups, t_inputrec *ir, t_state *state) { /* Should match the names in mdebin.c */ static const char *boxvel_nm[] = { "Box-Vel-XX", "Box-Vel-YY", "Box-Vel-ZZ", "Box-Vel-YX", "Box-Vel-ZX", "Box-Vel-ZY" }; static const char *baro_nm[] = { "Barostat" }; int ind0[] = { XX, YY, ZZ, YY, ZZ, ZZ }; int ind1[] = { XX, YY, ZZ, XX, XX, YY }; int nre, nfr, i, j, ni, npcoupl; char buf[STRLEN]; const char *bufi; gmx_enxnm_t *enm = NULL; t_enxframe *fr; ener_file_t in; in = open_enx(fn, "r"); do_enxnms(in, &nre, &enm); snew(fr, 1); nfr = 0; while ((nfr == 0 || fr->t != t) && do_enx(in, fr)) { nfr++; } close_enx(in); fprintf(stderr, "\n"); if (nfr == 0 || fr->t != t) { gmx_fatal(FARGS, "Could not find frame with time %f in '%s'", t, fn); } npcoupl = TRICLINIC(ir->compress) ? 6 : 3; if (ir->epc == epcPARRINELLORAHMAN) { clear_mat(state->boxv); for (i = 0; i < npcoupl; i++) { state->boxv[ind0[i]][ind1[i]] = find_energy(boxvel_nm[i], nre, enm, fr); } fprintf(stderr, "\nREAD %d BOX VELOCITIES FROM %s\n\n", npcoupl, fn); } if (ir->etc == etcNOSEHOOVER) { char cns[20]; cns[0] = '\0'; for (i = 0; i < state->ngtc; i++) { ni = groups->grps[egcTC].nm_ind[i]; bufi = *(groups->grpname[ni]); for (j = 0; (j < state->nhchainlength); j++) { if (IR_NVT_TROTTER(ir)) { sprintf(cns, "-%d", j); } sprintf(buf, "Xi%s-%s", cns, bufi); state->nosehoover_xi[i] = find_energy(buf, nre, enm, fr); sprintf(buf, "vXi%s-%s", cns, bufi); state->nosehoover_vxi[i] = find_energy(buf, nre, enm, fr); } } fprintf(stderr, "\nREAD %d NOSE-HOOVER Xi chains FROM %s\n\n", state->ngtc, fn); if (IR_NPT_TROTTER(ir) || IR_NPH_TROTTER(ir)) { for (i = 0; i < state->nnhpres; i++) { bufi = baro_nm[0]; /* All barostat DOF's together for now */ for (j = 0; (j < state->nhchainlength); j++) { sprintf(buf, "Xi-%d-%s", j, bufi); state->nhpres_xi[i] = find_energy(buf, nre, enm, fr); sprintf(buf, "vXi-%d-%s", j, bufi); state->nhpres_vxi[i] = find_energy(buf, nre, enm, fr); } } fprintf(stderr, "\nREAD %d NOSE-HOOVER BAROSTAT Xi chains FROM %s\n\n", state->nnhpres, fn); } } free_enxnms(nre, enm); free_enxframe(fr); sfree(fr); }