t_mdatoms *init_mdatoms(FILE *fp, gmx_mtop_t *mtop, gmx_bool bFreeEnergy) { int mb, a, g, nmol; double tmA, tmB; t_atom *atom; t_mdatoms *md; gmx_mtop_atomloop_all_t aloop; t_ilist *ilist; snew(md, 1); md->nenergrp = mtop->groups.grps[egcENER].nr; md->bVCMgrps = FALSE; tmA = 0.0; tmB = 0.0; aloop = gmx_mtop_atomloop_all_init(mtop); while (gmx_mtop_atomloop_all_next(aloop, &a, &atom)) { if (ggrpnr(&mtop->groups, egcVCM, a) > 0) { md->bVCMgrps = TRUE; } if (bFreeEnergy && PERTURBED(*atom)) { md->nPerturbed++; if (atom->mB != atom->m) { md->nMassPerturbed++; } if (atom->qB != atom->q) { md->nChargePerturbed++; } if (atom->typeB != atom->type) { md->nTypePerturbed++; } } tmA += atom->m; tmB += atom->mB; } md->tmassA = tmA; md->tmassB = tmB; if (bFreeEnergy && fp) { fprintf(fp, "There are %d atoms and %d charges for free energy perturbation\n", md->nPerturbed, md->nChargePerturbed); } md->bOrires = gmx_mtop_ftype_count(mtop, F_ORIRES); return md; }
void check_ir_old_tpx_versions(t_commrec *cr, FILE *fplog, t_inputrec *ir, gmx_mtop_t *mtop) { /* Check required for old tpx files */ if (IR_TWINRANGE(*ir) && ir->nstlist > 1 && ir->nstcalcenergy % ir->nstlist != 0) { md_print_warn(cr, fplog, "Old tpr file with twin-range settings: modifying energy calculation and/or T/P-coupling frequencies\n"); if (gmx_mtop_ftype_count(mtop, F_CONSTR) + gmx_mtop_ftype_count(mtop, F_CONSTRNC) > 0 && ir->eConstrAlg == econtSHAKE) { md_print_warn(cr, fplog, "With twin-range cut-off's and SHAKE the virial and pressure are incorrect\n"); if (ir->epc != epcNO) { gmx_fatal(FARGS, "Can not do pressure coupling with twin-range cut-off's and SHAKE"); } } check_nst_param(fplog, cr, "nstlist", ir->nstlist, "nstcalcenergy", &ir->nstcalcenergy); if (ir->epc != epcNO) { check_nst_param(fplog, cr, "nstlist", ir->nstlist, "nstpcouple", &ir->nstpcouple); } check_nst_param(fplog, cr, "nstcalcenergy", ir->nstcalcenergy, "nstenergy", &ir->nstenergy); check_nst_param(fplog, cr, "nstcalcenergy", ir->nstcalcenergy, "nstlog", &ir->nstlog); if (ir->efep != efepNO) { check_nst_param(fplog, cr, "nstcalcenergy", ir->nstcalcenergy, "nstdhdl", &ir->fepvals->nstdhdl); } } if (EI_VV(ir->eI) && IR_TWINRANGE(*ir) && ir->nstlist > 1) { gmx_fatal(FARGS, "Twin-range multiple time stepping does not work with integrator %s.", ei_names[ir->eI]); } }
void init_dihres(FILE *fplog,gmx_mtop_t *mtop,t_inputrec *ir,t_fcdata *fcd) { int count; fcd->dihre_fc = ir->dihre_fc; count = gmx_mtop_ftype_count(mtop,F_DIHRES); if (fplog && count) { fprintf(fplog,"There are %d dihedral restraints\n",count); } }
gmx_constr_t init_constraints(FILE *fplog, gmx_mtop_t *mtop, t_inputrec *ir, gmx_edsam_t ed, t_state *state, t_commrec *cr) { int ncon, nset, nmol, settle_type, i, natoms, mt, nflexcon; struct gmx_constr *constr; char *env; t_ilist *ilist; gmx_mtop_ilistloop_t iloop; ncon = gmx_mtop_ftype_count(mtop, F_CONSTR) + gmx_mtop_ftype_count(mtop, F_CONSTRNC); nset = gmx_mtop_ftype_count(mtop, F_SETTLE); if (ncon+nset == 0 && ir->ePull != epullCONSTRAINT && ed == NULL) { return NULL; } snew(constr, 1); constr->ncon_tot = ncon; constr->nflexcon = 0; if (ncon > 0) { constr->n_at2con_mt = mtop->nmoltype; snew(constr->at2con_mt, constr->n_at2con_mt); for (mt = 0; mt < mtop->nmoltype; mt++) { constr->at2con_mt[mt] = make_at2con(0, mtop->moltype[mt].atoms.nr, mtop->moltype[mt].ilist, mtop->ffparams.iparams, EI_DYNAMICS(ir->eI), &nflexcon); for (i = 0; i < mtop->nmolblock; i++) { if (mtop->molblock[i].type == mt) { constr->nflexcon += mtop->molblock[i].nmol*nflexcon; } } } if (constr->nflexcon > 0) { if (fplog) { fprintf(fplog, "There are %d flexible constraints\n", constr->nflexcon); if (ir->fc_stepsize == 0) { fprintf(fplog, "\n" "WARNING: step size for flexible constraining = 0\n" " All flexible constraints will be rigid.\n" " Will try to keep all flexible constraints at their original length,\n" " but the lengths may exhibit some drift.\n\n"); constr->nflexcon = 0; } } if (constr->nflexcon > 0) { please_cite(fplog, "Hess2002"); } } if (ir->eConstrAlg == econtLINCS) { constr->lincsd = init_lincs(fplog, mtop, constr->nflexcon, constr->at2con_mt, DOMAINDECOMP(cr) && cr->dd->bInterCGcons, ir->nLincsIter, ir->nProjOrder); } if (ir->eConstrAlg == econtSHAKE) { if (DOMAINDECOMP(cr) && cr->dd->bInterCGcons) { gmx_fatal(FARGS, "SHAKE is not supported with domain decomposition and constraint that cross charge group boundaries, use LINCS"); } if (constr->nflexcon) { gmx_fatal(FARGS, "For this system also velocities and/or forces need to be constrained, this can not be done with SHAKE, you should select LINCS"); } please_cite(fplog, "Ryckaert77a"); if (ir->bShakeSOR) { please_cite(fplog, "Barth95a"); } constr->shaked = shake_init(); } } if (nset > 0) { please_cite(fplog, "Miyamoto92a"); constr->bInterCGsettles = inter_charge_group_settles(mtop); /* Check that we have only one settle type */ settle_type = -1; iloop = gmx_mtop_ilistloop_init(mtop); while (gmx_mtop_ilistloop_next(iloop, &ilist, &nmol)) { for (i = 0; i < ilist[F_SETTLE].nr; i += 4) { if (settle_type == -1) { settle_type = ilist[F_SETTLE].iatoms[i]; } else if (ilist[F_SETTLE].iatoms[i] != settle_type) { gmx_fatal(FARGS, "The [molecules] section of your topology specifies more than one block of\n" "a [moleculetype] with a [settles] block. Only one such is allowed. If you\n" "are trying to partition your solvent into different *groups* (e.g. for\n" "freezing, T-coupling, etc.) then you are using the wrong approach. Index\n" "files specify groups. Otherwise, you may wish to change the least-used\n" "block of molecules with SETTLE constraints into 3 normal constraints."); } } } constr->n_at2settle_mt = mtop->nmoltype; snew(constr->at2settle_mt, constr->n_at2settle_mt); for (mt = 0; mt < mtop->nmoltype; mt++) { constr->at2settle_mt[mt] = make_at2settle(mtop->moltype[mt].atoms.nr, &mtop->moltype[mt].ilist[F_SETTLE]); } } constr->maxwarn = 999; env = getenv("GMX_MAXCONSTRWARN"); if (env) { constr->maxwarn = 0; sscanf(env, "%d", &constr->maxwarn); if (fplog) { fprintf(fplog, "Setting the maximum number of constraint warnings to %d\n", constr->maxwarn); } if (MASTER(cr)) { fprintf(stderr, "Setting the maximum number of constraint warnings to %d\n", constr->maxwarn); } } if (constr->maxwarn < 0 && fplog) { fprintf(fplog, "maxwarn < 0, will not stop on constraint errors\n"); } constr->warncount_lincs = 0; constr->warncount_settle = 0; /* Initialize the essential dynamics sampling. * Put the pointer to the ED struct in constr */ constr->ed = ed; if (ed != NULL || state->edsamstate.nED > 0) { init_edsam(mtop, ir, cr, ed, state->x, state->box, &state->edsamstate); } constr->warn_mtop = mtop; return constr; }
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 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_lincsdata_t init_lincs(FILE *fplog,gmx_mtop_t *mtop, int nflexcon_global,t_blocka *at2con, gmx_bool bPLINCS,int nIter,int nProjOrder) { struct gmx_lincsdata *li; int mb; gmx_moltype_t *molt; if (fplog) { fprintf(fplog,"\nInitializing%s LINear Constraint Solver\n", bPLINCS ? " Parallel" : ""); } snew(li,1); li->ncg = gmx_mtop_ftype_count(mtop,F_CONSTR) + gmx_mtop_ftype_count(mtop,F_CONSTRNC); li->ncg_flex = nflexcon_global; li->ncg_triangle = 0; for(mb=0; mb<mtop->nmolblock; mb++) { molt = &mtop->moltype[mtop->molblock[mb].type]; li->ncg_triangle += mtop->molblock[mb].nmol* count_triangle_constraints(molt->ilist, &at2con[mtop->molblock[mb].type]); } li->nIter = nIter; li->nOrder = nProjOrder; if (bPLINCS || li->ncg_triangle > 0) { please_cite(fplog,"Hess2008a"); } else { please_cite(fplog,"Hess97a"); } if (fplog) { fprintf(fplog,"The number of constraints is %d\n",li->ncg); if (bPLINCS) { fprintf(fplog,"There are inter charge-group constraints,\n" "will communicate selected coordinates each lincs iteration\n"); } if (li->ncg_triangle > 0) { fprintf(fplog, "%d constraints are involved in constraint triangles,\n" "will apply an additional matrix expansion of order %d for couplings\n" "between constraints inside triangles\n", li->ncg_triangle,li->nOrder); } } return li; }
void init_disres(FILE *fplog,const gmx_mtop_t *mtop, t_inputrec *ir,const t_commrec *cr,gmx_bool bPartDecomp, t_fcdata *fcd,t_state *state) { int fa,nmol,i,npair,np; t_iparams *ip; t_disresdata *dd; history_t *hist; gmx_mtop_ilistloop_t iloop; t_ilist *il; char *ptr; dd = &(fcd->disres); if (gmx_mtop_ftype_count(mtop,F_DISRES) == 0) { dd->nres = 0; return; } if (fplog) { fprintf(fplog,"Initializing the distance restraints\n"); } if (ir->eDisre == edrEnsemble) { gmx_fatal(FARGS,"Sorry, distance restraints with ensemble averaging over multiple molecules in one system are not functional in this version of GROMACS"); } dd->dr_weighting = ir->eDisreWeighting; dd->dr_fc = ir->dr_fc; if (EI_DYNAMICS(ir->eI)) { dd->dr_tau = ir->dr_tau; } else { dd->dr_tau = 0.0; } if (dd->dr_tau == 0.0) { dd->dr_bMixed = FALSE; dd->ETerm = 0.0; } else { dd->dr_bMixed = ir->bDisreMixed; dd->ETerm = exp(-(ir->delta_t/ir->dr_tau)); } dd->ETerm1 = 1.0 - dd->ETerm; ip = mtop->ffparams.iparams; dd->nres = 0; dd->npair = 0; iloop = gmx_mtop_ilistloop_init(mtop); while (gmx_mtop_ilistloop_next(iloop,&il,&nmol)) { np = 0; for(fa=0; fa<il[F_DISRES].nr; fa+=3) { np++; npair = mtop->ffparams.iparams[il[F_DISRES].iatoms[fa]].disres.npair; if (np == npair) { dd->nres += (ir->eDisre==edrEnsemble ? 1 : nmol)*npair; dd->npair += nmol*npair; np = 0; } } } if (cr && PAR(cr) && !bPartDecomp) { /* Temporary check, will be removed when disre is implemented with DD */ const char *notestr="NOTE: atoms involved in distance restraints should be within the longest cut-off distance, if this is not the case mdrun generates a fatal error, in that case use particle decomposition (mdrun option -pd)"; if (MASTER(cr)) fprintf(stderr,"\n%s\n\n",notestr); if (fplog) fprintf(fplog,"%s\n",notestr); if (dd->dr_tau != 0 || ir->eDisre == edrEnsemble || cr->ms != NULL || dd->nres != dd->npair) { gmx_fatal(FARGS,"Time or ensemble averaged or multiple pair distance restraints do not work (yet) with domain decomposition, use particle decomposition (mdrun option -pd)"); } if (ir->nstdisreout != 0) { if (fplog) { fprintf(fplog,"\nWARNING: Can not write distance restraint data to energy file with domain decomposition\n\n"); } if (MASTER(cr)) { fprintf(stderr,"\nWARNING: Can not write distance restraint data to energy file with domain decomposition\n"); } ir->nstdisreout = 0; } } snew(dd->rt,dd->npair); if (dd->dr_tau != 0.0) { hist = &state->hist; /* Set the "history lack" factor to 1 */ state->flags |= (1<<estDISRE_INITF); hist->disre_initf = 1.0; /* Allocate space for the r^-3 time averages */ state->flags |= (1<<estDISRE_RM3TAV); hist->ndisrepairs = dd->npair; snew(hist->disre_rm3tav,hist->ndisrepairs); } /* Allocate space for a copy of rm3tav, * so we can call do_force without modifying the state. */ snew(dd->rm3tav,dd->npair); /* Allocate Rt_6 and Rtav_6 consecutively in memory so they can be * averaged over the processors in one call (in calc_disre_R_6) */ snew(dd->Rt_6,2*dd->nres); dd->Rtav_6 = &(dd->Rt_6[dd->nres]); ptr = getenv("GMX_DISRE_ENSEMBLE_SIZE"); if (cr && cr->ms != NULL && ptr != NULL) { #ifdef GMX_MPI dd->nsystems = 0; sscanf(ptr,"%d",&dd->nsystems); if (fplog) { fprintf(fplog,"Found GMX_DISRE_ENSEMBLE_SIZE set to %d systems per ensemble\n",dd->nsystems); } check_multi_int(fplog,cr->ms,dd->nsystems, "the number of systems per ensemble"); if (dd->nsystems <= 0 || cr->ms->nsim % dd->nsystems != 0) { gmx_fatal(FARGS,"The number of systems %d is not divisible by the number of systems per ensemble %d\n",cr->ms->nsim,dd->nsystems); } /* Split the inter-master communicator into different ensembles */ MPI_Comm_split(cr->ms->mpi_comm_masters, cr->ms->sim/dd->nsystems, cr->ms->sim, &dd->mpi_comm_ensemble); if (fplog) { fprintf(fplog,"Our ensemble consists of systems:"); for(i=0; i<dd->nsystems; i++) { fprintf(fplog," %d", (cr->ms->sim/dd->nsystems)*dd->nsystems+i); } fprintf(fplog,"\n"); } snew(dd->Rtl_6,dd->nres); #endif } else { dd->nsystems = 1; dd->Rtl_6 = dd->Rt_6; } if (dd->npair > 0) { if (fplog) { fprintf(fplog,"There are %d distance restraints involving %d atom pairs\n",dd->nres,dd->npair); } if (cr && cr->ms) { check_multi_int(fplog,cr->ms,fcd->disres.nres, "the number of distance restraints"); } please_cite(fplog,"Tropp80a"); please_cite(fplog,"Torda89a"); } }
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; }
void init_disres(FILE *fplog, const gmx_mtop_t *mtop, t_inputrec *ir, const t_commrec *cr, t_fcdata *fcd, t_state *state, gmx_bool bIsREMD) { int fa, nmol, npair, np; t_disresdata *dd; history_t *hist; gmx_mtop_ilistloop_t iloop; t_ilist *il; char *ptr; dd = &(fcd->disres); if (gmx_mtop_ftype_count(mtop, F_DISRES) == 0) { dd->nres = 0; return; } if (fplog) { fprintf(fplog, "Initializing the distance restraints\n"); } if (ir->eDisre == edrEnsemble) { gmx_fatal(FARGS, "Sorry, distance restraints with ensemble averaging over multiple molecules in one system are not functional in this version of GROMACS"); } dd->dr_weighting = ir->eDisreWeighting; dd->dr_fc = ir->dr_fc; if (EI_DYNAMICS(ir->eI)) { dd->dr_tau = ir->dr_tau; } else { dd->dr_tau = 0.0; } if (dd->dr_tau == 0.0) { dd->dr_bMixed = FALSE; dd->ETerm = 0.0; } else { dd->dr_bMixed = ir->bDisreMixed; dd->ETerm = std::exp(-(ir->delta_t/ir->dr_tau)); } dd->ETerm1 = 1.0 - dd->ETerm; dd->nres = 0; dd->npair = 0; iloop = gmx_mtop_ilistloop_init(mtop); while (gmx_mtop_ilistloop_next(iloop, &il, &nmol)) { np = 0; for (fa = 0; fa < il[F_DISRES].nr; fa += 3) { np++; npair = mtop->ffparams.iparams[il[F_DISRES].iatoms[fa]].disres.npair; if (np == npair) { dd->nres += (ir->eDisre == edrEnsemble ? 1 : nmol)*npair; dd->npair += nmol*npair; np = 0; } } } if (cr && PAR(cr)) { /* Temporary check, will be removed when disre is implemented with DD */ const char *notestr = "NOTE: atoms involved in distance restraints should be within the same domain. If this is not the case mdrun generates a fatal error. If you encounter this, use a single MPI rank (Verlet+OpenMP+GPUs work fine)."; if (MASTER(cr)) { fprintf(stderr, "\n%s\n\n", notestr); } if (fplog) { fprintf(fplog, "%s\n", notestr); } if (dd->dr_tau != 0 || ir->eDisre == edrEnsemble || cr->ms != NULL || dd->nres != dd->npair) { gmx_fatal(FARGS, "Time or ensemble averaged or multiple pair distance restraints do not work (yet) with domain decomposition, use a single MPI rank%s", cr->ms ? " per simulation" : ""); } if (ir->nstdisreout != 0) { if (fplog) { fprintf(fplog, "\nWARNING: Can not write distance restraint data to energy file with domain decomposition\n\n"); } if (MASTER(cr)) { fprintf(stderr, "\nWARNING: Can not write distance restraint data to energy file with domain decomposition\n"); } ir->nstdisreout = 0; } } snew(dd->rt, dd->npair); if (dd->dr_tau != 0.0) { hist = &state->hist; /* Set the "history lack" factor to 1 */ state->flags |= (1<<estDISRE_INITF); hist->disre_initf = 1.0; /* Allocate space for the r^-3 time averages */ state->flags |= (1<<estDISRE_RM3TAV); hist->ndisrepairs = dd->npair; snew(hist->disre_rm3tav, hist->ndisrepairs); } /* Allocate space for a copy of rm3tav, * so we can call do_force without modifying the state. */ snew(dd->rm3tav, dd->npair); /* Allocate Rt_6 and Rtav_6 consecutively in memory so they can be * averaged over the processors in one call (in calc_disre_R_6) */ snew(dd->Rt_6, 2*dd->nres); dd->Rtav_6 = &(dd->Rt_6[dd->nres]); ptr = getenv("GMX_DISRE_ENSEMBLE_SIZE"); if (cr && cr->ms != NULL && ptr != NULL && !bIsREMD) { #ifdef GMX_MPI dd->nsystems = 0; sscanf(ptr, "%d", &dd->nsystems); if (fplog) { fprintf(fplog, "Found GMX_DISRE_ENSEMBLE_SIZE set to %d systems per ensemble\n", dd->nsystems); } /* This check is only valid on MASTER(cr), so probably * ensemble-averaged distance restraints are broken on more * than one processor per simulation system. */ if (MASTER(cr)) { check_multi_int(fplog, cr->ms, dd->nsystems, "the number of systems per ensemble", FALSE); } gmx_bcast_sim(sizeof(int), &dd->nsystems, cr); /* We use to allow any value of nsystems which was a divisor * of ms->nsim. But this required an extra communicator which * was stored in t_fcdata. This pulled in mpi.h in nearly all C files. */ if (!(cr->ms->nsim == 1 || cr->ms->nsim == dd->nsystems)) { gmx_fatal(FARGS, "GMX_DISRE_ENSEMBLE_SIZE (%d) is not equal to 1 or the number of systems (option -multi) %d", dd->nsystems, cr->ms->nsim); } if (fplog) { fprintf(fplog, "Our ensemble consists of systems:"); for (int i = 0; i < dd->nsystems; i++) { fprintf(fplog, " %d", (cr->ms->sim/dd->nsystems)*dd->nsystems+i); } fprintf(fplog, "\n"); } snew(dd->Rtl_6, dd->nres); #endif } else { dd->nsystems = 1; dd->Rtl_6 = dd->Rt_6; } if (dd->npair > 0) { if (fplog) { fprintf(fplog, "There are %d distance restraints involving %d atom pairs\n", dd->nres, dd->npair); } /* Have to avoid g_disre de-referencing cr blindly, mdrun not * doing consistency checks for ensemble-averaged distance * restraints when that's not happening, and only doing those * checks from appropriate processes (since check_multi_int is * too broken to check whether the communication will * succeed...) */ if (cr && cr->ms && dd->nsystems > 1 && MASTER(cr)) { check_multi_int(fplog, cr->ms, fcd->disres.nres, "the number of distance restraints", FALSE); } please_cite(fplog, "Tropp80a"); please_cite(fplog, "Torda89a"); } }
gmx_lincsdata_t init_lincs(FILE *fplog,gmx_mtop_t *mtop, int nflexcon_global,t_blocka *at2con, gmx_bool bPLINCS,int nIter,int nProjOrder) { struct gmx_lincsdata *li; int mb; gmx_moltype_t *molt; if (fplog) { fprintf(fplog,"\nInitializing%s LINear Constraint Solver\n", bPLINCS ? " Parallel" : ""); } snew(li,1); li->ncg = gmx_mtop_ftype_count(mtop,F_CONSTR) + gmx_mtop_ftype_count(mtop,F_CONSTRNC); li->ncg_flex = nflexcon_global; li->ncg_triangle = 0; for(mb=0; mb<mtop->nmolblock; mb++) { molt = &mtop->moltype[mtop->molblock[mb].type]; li->ncg_triangle += mtop->molblock[mb].nmol* count_triangle_constraints(molt->ilist, &at2con[mtop->molblock[mb].type]); } li->nIter = nIter; li->nOrder = nProjOrder; /* LINCS can run on any number of threads. * Currently the number is fixed for the whole simulation, * but it could be set in set_lincs(). */ li->nth = gmx_omp_nthreads_get(emntLINCS); if (li->nth == 1) { snew(li->th,1); } else { /* Allocate an extra elements for "thread-overlap" constraints */ snew(li->th,li->nth+1); } if (debug) { fprintf(debug,"LINCS: using %d threads\n",li->nth); } if (bPLINCS || li->ncg_triangle > 0) { please_cite(fplog,"Hess2008a"); } else { please_cite(fplog,"Hess97a"); } if (fplog) { fprintf(fplog,"The number of constraints is %d\n",li->ncg); if (bPLINCS) { fprintf(fplog,"There are inter charge-group constraints,\n" "will communicate selected coordinates each lincs iteration\n"); } if (li->ncg_triangle > 0) { fprintf(fplog, "%d constraints are involved in constraint triangles,\n" "will apply an additional matrix expansion of order %d for couplings\n" "between constraints inside triangles\n", li->ncg_triangle,li->nOrder); } } return li; }
t_mdebin *init_mdebin(int fp_ene, const gmx_mtop_t *mtop, const t_inputrec *ir) { char *ener_nm[F_NRE]; static char *vir_nm[] = { "Vir-XX", "Vir-XY", "Vir-XZ", "Vir-YX", "Vir-YY", "Vir-YZ", "Vir-ZX", "Vir-ZY", "Vir-ZZ" }; static char *sv_nm[] = { "ShakeVir-XX", "ShakeVir-XY", "ShakeVir-XZ", "ShakeVir-YX", "ShakeVir-YY", "ShakeVir-YZ", "ShakeVir-ZX", "ShakeVir-ZY", "ShakeVir-ZZ" }; static char *fv_nm[] = { "ForceVir-XX", "ForceVir-XY", "ForceVir-XZ", "ForceVir-YX", "ForceVir-YY", "ForceVir-YZ", "ForceVir-ZX", "ForceVir-ZY", "ForceVir-ZZ" }; static char *pres_nm[] = { "Pres-XX (bar)","Pres-XY (bar)","Pres-XZ (bar)", "Pres-YX (bar)","Pres-YY (bar)","Pres-YZ (bar)", "Pres-ZX (bar)","Pres-ZY (bar)","Pres-ZZ (bar)" }; static char *surft_nm[] = { "#Surf*SurfTen" }; static char *mu_nm[] = { "Mu-X", "Mu-Y", "Mu-Z" }; static char *vcos_nm[] = { "2CosZ*Vel-X" }; static char *visc_nm[] = { "1/Viscosity (SI)" }; static char **grpnms; const gmx_groups_t *groups; char **gnm; char buf[256]; t_mdebin *md; int i,j,ni,nj,n,k,kk,ncon,nset; bool bBHAM,b14; f_nre = 0; // otherwise, multiple calls to mdrunner_integrate are not possible!NnCrmsd; 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); bConstr = (ncon > 0 || nset > 0); bConstrVir = FALSE; if (bConstr) { if (ncon > 0 && ir->eConstrAlg == econtLINCS) { if (ir->eI == eiSD2) nCrmsd = 2; else nCrmsd = 1; } bConstrVir = (getenv("GMX_CONSTRAINTVIR") != NULL); } else { nCrmsd = 0; } for(i=0; i<F_NRE; i++) { bEner[i] = FALSE; if (i == F_LJ) bEner[i] = !bBHAM; else if (i == F_BHAM) bEner[i] = bBHAM; else if (i == F_EQM) bEner[i] = ir->bQMMM; else if (i == F_COUL_LR) bEner[i] = (ir->rcoulomb > ir->rlist); else if (i == F_LJ_LR) bEner[i] = (!bBHAM && ir->rvdw > ir->rlist); else if (i == F_BHAM_LR) bEner[i] = (bBHAM && ir->rvdw > ir->rlist); else if (i == F_RF_EXCL) bEner[i] = (EEL_RF(ir->coulombtype) && ir->coulombtype != eelRF_NEC); else if (i == F_COUL_RECIP) bEner[i] = EEL_FULL(ir->coulombtype); else if (i == F_LJ14) bEner[i] = b14; else if (i == F_COUL14) bEner[i] = b14; else if (i == F_LJC14_Q || i == F_LJC_PAIRS_NB) bEner[i] = FALSE; else if ((i == F_DVDL) || (i == F_DKDL)) bEner[i] = (ir->efep != efepNO); else if (i == F_DGDL_CON) bEner[i] = (ir->efep != efepNO && bConstr); else if ((interaction_function[i].flags & IF_VSITE) || (i == F_CONSTR) || (i == F_SETTLE)) bEner[i] = FALSE; else if ((i == F_COUL_SR) || (i == F_EPOT) || (i == F_PRES) || (i==F_EQM)) bEner[i] = TRUE; else if ((i == F_ETOT) || (i == F_EKIN) || (i == F_TEMP)) bEner[i] = EI_DYNAMICS(ir->eI); else if (i == F_DISPCORR) bEner[i] = (ir->eDispCorr != edispcNO); else if (i == F_DISRESVIOL) bEner[i] = (gmx_mtop_ftype_count(mtop,F_DISRES) > 0); else if (i == F_ORIRESDEV) bEner[i] = (gmx_mtop_ftype_count(mtop,F_ORIRES) > 0); else if (i == F_CONNBONDS) bEner[i] = FALSE; else if (i == F_COM_PULL) bEner[i] = (ir->ePull == epullUMBRELLA || ir->ePull == epullCONST_F); else if (i == F_ECONSERVED) bEner[i] = ((ir->etc == etcNOSEHOOVER || ir->etc == etcVRESCALE) && ir->epc == epcNO); else bEner[i] = (gmx_mtop_ftype_count(mtop,i) > 0); } for(i=0; i<F_NRE; i++) if (bEner[i]) { ener_nm[f_nre]=interaction_function[i].longname; f_nre++; } epc = ir->epc; bTricl = TRICLINIC(ir->compress) || TRICLINIC(ir->deform); bDynBox = DYNAMIC_BOX(*ir); etc = ir->etc; /* Energy monitoring */ snew(md,1); md->ebin = mk_ebin(); md->ie = get_ebin_space(md->ebin,f_nre,ener_nm); if (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,nCrmsd,conrmsd_nm); } if (bDynBox) md->ib = get_ebin_space(md->ebin, bTricl ? NTRICLBOXS : NBOXS, bTricl ? tricl_boxs_nm : boxs_nm); if (bConstrVir) { md->isvir = get_ebin_space(md->ebin,asize(sv_nm),sv_nm); md->ifvir = get_ebin_space(md->ebin,asize(fv_nm),fv_nm); } md->ivir = get_ebin_space(md->ebin,asize(vir_nm),vir_nm); md->ipres = get_ebin_space(md->ebin,asize(pres_nm),pres_nm); md->isurft = get_ebin_space(md->ebin,asize(surft_nm),surft_nm); if (epc == epcPARRINELLORAHMAN) { md->ipc = get_ebin_space(md->ebin,bTricl ? 6 : 3,boxvel_nm); } md->imu = get_ebin_space(md->ebin,asize(mu_nm),mu_nm); if (ir->cos_accel != 0) { md->ivcos = get_ebin_space(md->ebin,asize(vcos_nm),vcos_nm); md->ivisc = get_ebin_space(md->ebin,asize(visc_nm),visc_nm); } if (ir->rcoulomb > ir->rlist) bEInd[egCOULLR] = TRUE; if (!bBHAM) { if (ir->rvdw > ir->rlist) bEInd[egLJLR] = TRUE; } else { bEInd[egLJSR] = FALSE; bEInd[egBHAMSR] = TRUE; if (ir->rvdw > ir->rlist) bEInd[egBHAMLR] = TRUE; } if (b14) { bEInd[egLJ14] = TRUE; bEInd[egCOUL14] = TRUE; } md->nEc=0; for(i=0; (i<egNR); i++) if (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 (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,gnm); 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; snew(grpnms,md->nTC); 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,grpnms); sfree(*grpnms); if (etc == etcNOSEHOOVER) { for(i=0; (i<md->nTC); i++) { ni=groups->grps[egcTC].nm_ind[i]; sprintf(buf,"Xi-%s",*(groups->grpname[ni])); grpnms[i]=strdup(buf); } md->itc=get_ebin_space(md->ebin,md->nTC,grpnms); sfree(*grpnms); } else if (etc == etcBERENDSEN || etc == etcYES || 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->nTC,grpnms); sfree(*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,grpnms); sfree(*grpnms); sfree(grpnms); } if (fp_ene != -1) do_enxnms(fp_ene,&md->ebin->nener,&md->ebin->enm); return md; }