Exemple #1
0
void set_state_entries(t_state *state, const t_inputrec *ir)
{
    /* The entries in the state in the tpx file might not correspond
     * with what is needed, so we correct this here.
     */
    state->flags = 0;
    if (ir->efep != efepNO || ir->bExpanded)
    {
        state->flags |= (1<<estLAMBDA);
        state->flags |= (1<<estFEPSTATE);
    }
    state->flags |= (1<<estX);
    if (state->lambda == NULL)
    {
        snew(state->lambda, efptNR);
    }
    if (state->x == NULL)
    {
        snew(state->x, state->nalloc);
    }
    if (EI_DYNAMICS(ir->eI))
    {
        state->flags |= (1<<estV);
        if (state->v == NULL)
        {
            snew(state->v, state->nalloc);
        }
    }
    if (ir->eI == eiSD2)
    {
        state->flags |= (1<<estSDX);
        if (state->sd_X == NULL)
        {
            /* sd_X is not stored in the tpx file, so we need to allocate it */
            snew(state->sd_X, state->nalloc);
        }
    }
    if (ir->eI == eiCG)
    {
        state->flags |= (1<<estCGP);
        if (state->cg_p == NULL)
        {
            /* cg_p is not stored in the tpx file, so we need to allocate it */
            snew(state->cg_p, state->nalloc);
        }
    }

    state->nnhpres = 0;
    if (ir->ePBC != epbcNONE)
    {
        state->flags |= (1<<estBOX);
        if (PRESERVE_SHAPE(*ir))
        {
            state->flags |= (1<<estBOX_REL);
        }
        if ((ir->epc == epcPARRINELLORAHMAN) || (ir->epc == epcMTTK))
        {
            state->flags |= (1<<estBOXV);
        }
        if (ir->epc != epcNO)
        {
            if (IR_NPT_TROTTER(ir) || (IR_NPH_TROTTER(ir)))
            {
                state->nnhpres = 1;
                state->flags  |= (1<<estNHPRES_XI);
                state->flags  |= (1<<estNHPRES_VXI);
                state->flags  |= (1<<estSVIR_PREV);
                state->flags  |= (1<<estFVIR_PREV);
                state->flags  |= (1<<estVETA);
                state->flags  |= (1<<estVOL0);
            }
            else
            {
                state->flags |= (1<<estPRES_PREV);
            }
        }
    }

    if (ir->etc == etcNOSEHOOVER)
    {
        state->flags |= (1<<estNH_XI);
        state->flags |= (1<<estNH_VXI);
    }

    if (ir->etc == etcVRESCALE)
    {
        state->flags |= (1<<estTC_INT);
    }

    init_gtc_state(state, state->ngtc, state->nnhpres, ir->opts.nhchainlength); /* allocate the space for nose-hoover chains */
    init_ekinstate(&state->ekinstate, ir);

    init_energyhistory(&state->enerhist);
    init_df_history(&state->dfhist, ir->fepvals->n_lambda);
    state->swapstate.eSwapCoords = ir->eSwapCoords;
}
Exemple #2
0
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);
}
Exemple #3
0
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;
}
Exemple #4
0
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);

    md->bVir=TRUE;
    md->bPress=TRUE;
    md->bSurft=TRUE;
    md->bMu=TRUE;

    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 && ir->cutoff_scheme == ecutsGROUP);
        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_COUL && ir->fepvals->separate_dvdl[efptCOUL]) ||
                 (i == F_DVDL_VDW  && ir->fepvals->separate_dvdl[efptVDW]) ||
                 (i == F_DVDL_BONDED && ir->fepvals->separate_dvdl[efptBONDED]) ||
                 (i == F_DVDL_RESTRAINT && ir->fepvals->separate_dvdl[efptRESTRAINT]) ||
                 (i == F_DKDL && ir->fepvals->separate_dvdl[efptMASS]) ||
                 (i == F_DVDL && ir->fepvals->separate_dvdl[efptFEP]))
            md->bEner[i] = (ir->efep != efepNO);
        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_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 || ir->bRot);
        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

    /* for adress simulations, most energy terms are not meaningfull, and thus disabled*/
    if (ir->bAdress && !debug) {
        for (i = 0; i < F_NRE; i++) {
            md->bEner[i] = FALSE;
            if(i == F_EKIN){ md->bEner[i] = TRUE;}
            if(i == F_TEMP){ md->bEner[i] = TRUE;}
        }
        md->bVir=FALSE;
        md->bPress=FALSE;
        md->bSurft=FALSE;
        md->bMu=FALSE;
    }

    md->f_nre=0;
    for(i=0; i<F_NRE; i++)
    {
        if (md->bEner[i])
        {
            ener_nm[md->f_nre]=interaction_function[i].longname;
            md->f_nre++;
        }
    }

    md->epc = ir->epc;
    md->bDiagPres = !TRICLINIC(ir->ref_p);
    md->ref_p = (ir->ref_p[XX][XX]+ir->ref_p[YY][YY]+ir->ref_p[ZZ][ZZ])/DIM;
    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->bPrintNHChains = ir-> bPrintNHChains;
    md->bMTTK = (IR_NPT_TROTTER(ir) || IR_NPH_TROTTER(ir));
    md->bMu = NEED_MUTOT(*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);
        if (md->bDiagPres)
        {
            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);
    }
    if (md->bVir)
        md->ivir   = get_ebin_space(md->ebin,asize(vir_nm),vir_nm,unit_energy);
    if (md->bPress)
        md->ipres  = get_ebin_space(md->ebin,asize(pres_nm),pres_nm,unit_pres_bar);
    if (md->bSurft)
        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);
    }
    if (md->bMu)
    {
        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;
    /* for adress simulations, most energy terms are not meaningfull, and thus disabled*/
    if (!ir->bAdress){
        /*standard simulation*/
        md->nEg=n;
        md->nE=(n*(n+1))/2;
    }
    else if (!debug) {
        /*AdResS simulation*/
       md->nU=0;
       md->nEg=0;
       md->nE=0;
       md->nEc=0;
       md->isvir=FALSE;
    }
    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);

    if (md->etc == etcNOSEHOOVER)
    {
        if (md->bPrintNHChains)
        {
            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->fepvals->separate_dhdl_file == esepdhdlfileNO )
    {
        /* Currently dh histograms are only written with dynamics */
        if (EI_DYNAMICS(ir->eI))
        {
            snew(md->dhc, 1);

            mde_delta_h_coll_init(md->dhc, ir);
        }
        md->fp_dhdl = NULL;
    }
    else
    {
        md->fp_dhdl = fp_dhdl;
    }
    if (ir->bSimTemp) {
        int i;
        snew(md->temperatures,ir->fepvals->n_lambda);
        for (i=0;i<ir->fepvals->n_lambda;i++)
        {
            md->temperatures[i] = ir->simtempvals->temperatures[i];
        }
    }
    return md;
}