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, k, kk, ncon, nset; gmx_bool bBHAM, 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) { 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; } 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_RF_EXCL) { md->bEner[i] = (EEL_RF(ir->coulombtype) && ir->cutoff_scheme == ecutsGROUP); } else if (i == F_COUL_RECIP) { md->bEner[i] = EEL_FULL(ir->coulombtype); } else if (i == F_LJ_RECIP) { md->bEner[i] = EVDW_PME(ir->vdwtype); } 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->bPull && pull_have_potential(ir->pull_work)); } 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); } } 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 = inputrecDynamicBox(ir); md->etc = ir->etc; md->bNHC_trotter = inputrecNvtTrotter(ir); md->bPrintNHChains = ir->bPrintNHChains; md->bMTTK = (inputrecNptTrotter(ir) || inputrecNphTrotter(ir)); md->bMu = inputrecNeedMutot(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); } 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); } 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 (bBHAM) { md->bEInd[egLJSR] = FALSE; md->bEInd[egBHAMSR] = 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] = gmx_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)] = gmx_strdup(buf); sprintf(buf, "vXi-%d-%s", j, bufi); grpnms[2*(i*md->nNHC+j)+1] = gmx_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)] = gmx_strdup(buf); sprintf(buf, "vXi-%d-%s", j, bufi); grpnms[2*(i*md->nNHC+j)+1] = gmx_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] = gmx_strdup(buf); sprintf(buf, "vXi-%s", bufi); grpnms[2*i+1] = gmx_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] = gmx_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] = gmx_strdup(buf); sprintf(buf, "Uy-%s", *(groups->grpname[ni])); grpnms[3*i+YY] = gmx_strdup(buf); sprintf(buf, "Uz-%s", *(groups->grpname[ni])); grpnms[3*i+ZZ] = gmx_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; snew(md->dE, ir->fepvals->n_lambda); } else { md->fp_dhdl = fp_dhdl; snew(md->dE, ir->fepvals->n_lambda); } 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; }
void global_stat(gmx_global_stat_t gs, t_commrec *cr, gmx_enerdata_t *enerd, tensor fvir, tensor svir, rvec mu_tot, t_inputrec *inputrec, gmx_ekindata_t *ekind, gmx_constr_t constr, t_vcm *vcm, int nsig, real *sig, int *totalNumberOfBondedInteractions, gmx_bool bSumEkinhOld, int flags) /* instead of current system, gmx_booleans for summing virial, kinetic energy, and other terms */ { t_bin *rb; int *itc0, *itc1; int ie = 0, ifv = 0, isv = 0, irmsd = 0, imu = 0; int idedl = 0, idvdll = 0, idvdlnl = 0, iepl = 0, icm = 0, imass = 0, ica = 0, inb = 0; int isig = -1; int icj = -1, ici = -1, icx = -1; int inn[egNR]; real copyenerd[F_NRE]; int nener, j; real *rmsd_data = NULL; double nb; gmx_bool bVV, bTemp, bEner, bPres, bConstrVir, bEkinAveVel, bReadEkin; bool checkNumberOfBondedInteractions = flags & CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS; bVV = EI_VV(inputrec->eI); bTemp = flags & CGLO_TEMPERATURE; bEner = flags & CGLO_ENERGY; bPres = (flags & CGLO_PRESSURE); bConstrVir = (flags & CGLO_CONSTRAINT); bEkinAveVel = (inputrec->eI == eiVV || (inputrec->eI == eiVVAK && bPres)); bReadEkin = (flags & CGLO_READEKIN); rb = gs->rb; itc0 = gs->itc0; itc1 = gs->itc1; reset_bin(rb); /* This routine copies all the data to be summed to one big buffer * using the t_bin struct. */ /* First, we neeed to identify which enerd->term should be communicated. Temperature and pressure terms should only be communicated and summed when they need to be, to avoid repeating the sums and overcounting. */ nener = filter_enerdterm(enerd->term, TRUE, copyenerd, bTemp, bPres, bEner); /* First, the data that needs to be communicated with velocity verlet every time This is just the constraint virial.*/ if (bConstrVir) { isv = add_binr(rb, DIM*DIM, svir[0]); where(); } /* We need the force virial and the kinetic energy for the first time through with velocity verlet */ if (bTemp || !bVV) { if (ekind) { for (j = 0; (j < inputrec->opts.ngtc); j++) { if (bSumEkinhOld) { itc0[j] = add_binr(rb, DIM*DIM, ekind->tcstat[j].ekinh_old[0]); } if (bEkinAveVel && !bReadEkin) { itc1[j] = add_binr(rb, DIM*DIM, ekind->tcstat[j].ekinf[0]); } else if (!bReadEkin) { itc1[j] = add_binr(rb, DIM*DIM, ekind->tcstat[j].ekinh[0]); } } /* these probably need to be put into one of these categories */ where(); idedl = add_binr(rb, 1, &(ekind->dekindl)); where(); ica = add_binr(rb, 1, &(ekind->cosacc.mvcos)); where(); } } where(); if (bPres) { ifv = add_binr(rb, DIM*DIM, fvir[0]); } if (bEner) { where(); ie = add_binr(rb, nener, copyenerd); where(); if (constr) { rmsd_data = constr_rmsd_data(constr); if (rmsd_data) { irmsd = add_binr(rb, 2, rmsd_data); } } if (!inputrecNeedMutot(inputrec)) { imu = add_binr(rb, DIM, mu_tot); where(); } for (j = 0; (j < egNR); j++) { inn[j] = add_binr(rb, enerd->grpp.nener, enerd->grpp.ener[j]); } where(); if (inputrec->efep != efepNO) { idvdll = add_bind(rb, efptNR, enerd->dvdl_lin); idvdlnl = add_bind(rb, efptNR, enerd->dvdl_nonlin); if (enerd->n_lambda > 0) { iepl = add_bind(rb, enerd->n_lambda, enerd->enerpart_lambda); } } } if (vcm) { icm = add_binr(rb, DIM*vcm->nr, vcm->group_p[0]); where(); imass = add_binr(rb, vcm->nr, vcm->group_mass); where(); if (vcm->mode == ecmANGULAR) { icj = add_binr(rb, DIM*vcm->nr, vcm->group_j[0]); where(); icx = add_binr(rb, DIM*vcm->nr, vcm->group_x[0]); where(); ici = add_binr(rb, DIM*DIM*vcm->nr, vcm->group_i[0][0]); where(); } } if (checkNumberOfBondedInteractions) { nb = cr->dd->nbonded_local; inb = add_bind(rb, 1, &nb); } where(); if (nsig > 0) { isig = add_binr(rb, nsig, sig); } /* Global sum it all */ if (debug) { fprintf(debug, "Summing %d energies\n", rb->maxreal); } sum_bin(rb, cr); where(); /* Extract all the data locally */ if (bConstrVir) { extract_binr(rb, isv, DIM*DIM, svir[0]); } /* We need the force virial and the kinetic energy for the first time through with velocity verlet */ if (bTemp || !bVV) { if (ekind) { for (j = 0; (j < inputrec->opts.ngtc); j++) { if (bSumEkinhOld) { extract_binr(rb, itc0[j], DIM*DIM, ekind->tcstat[j].ekinh_old[0]); } if (bEkinAveVel && !bReadEkin) { extract_binr(rb, itc1[j], DIM*DIM, ekind->tcstat[j].ekinf[0]); } else if (!bReadEkin) { extract_binr(rb, itc1[j], DIM*DIM, ekind->tcstat[j].ekinh[0]); } } extract_binr(rb, idedl, 1, &(ekind->dekindl)); extract_binr(rb, ica, 1, &(ekind->cosacc.mvcos)); where(); } } if (bPres) { extract_binr(rb, ifv, DIM*DIM, fvir[0]); } if (bEner) { extract_binr(rb, ie, nener, copyenerd); if (rmsd_data) { extract_binr(rb, irmsd, 2, rmsd_data); } if (!inputrecNeedMutot(inputrec)) { extract_binr(rb, imu, DIM, mu_tot); } for (j = 0; (j < egNR); j++) { extract_binr(rb, inn[j], enerd->grpp.nener, enerd->grpp.ener[j]); } if (inputrec->efep != efepNO) { extract_bind(rb, idvdll, efptNR, enerd->dvdl_lin); extract_bind(rb, idvdlnl, efptNR, enerd->dvdl_nonlin); if (enerd->n_lambda > 0) { extract_bind(rb, iepl, enerd->n_lambda, enerd->enerpart_lambda); } } where(); filter_enerdterm(copyenerd, FALSE, enerd->term, bTemp, bPres, bEner); } if (vcm) { extract_binr(rb, icm, DIM*vcm->nr, vcm->group_p[0]); where(); extract_binr(rb, imass, vcm->nr, vcm->group_mass); where(); if (vcm->mode == ecmANGULAR) { extract_binr(rb, icj, DIM*vcm->nr, vcm->group_j[0]); where(); extract_binr(rb, icx, DIM*vcm->nr, vcm->group_x[0]); where(); extract_binr(rb, ici, DIM*DIM*vcm->nr, vcm->group_i[0][0]); where(); } } if (checkNumberOfBondedInteractions) { extract_bind(rb, inb, 1, &nb); *totalNumberOfBondedInteractions = static_cast<int>(nb+0.5); } if (nsig > 0) { extract_binr(rb, isig, nsig, sig); } where(); }