Esempio n. 1
0
void set_pull_init(t_inputrec *ir, gmx_mtop_t *mtop, rvec *x, matrix box, real lambda,
                   const output_env_t oenv)
{
    pull_params_t *pull;
    struct pull_t *pull_work;
    t_mdatoms     *md;
    t_pbc          pbc;
    int            c;
    double         t_start;

    pull      = ir->pull;
    pull_work = init_pull(NULL, pull, ir, 0, NULL, mtop, NULL, oenv, lambda, FALSE, 0);
    md        = init_mdatoms(NULL, mtop, ir->efep);
    atoms2md(mtop, ir, 0, NULL, mtop->natoms, md);
    if (ir->efep)
    {
        update_mdatoms(md, lambda);
    }

    set_pbc(&pbc, ir->ePBC, box);

    t_start = ir->init_t + ir->init_step*ir->delta_t;

    pull_calc_coms(NULL, pull_work, md, &pbc, t_start, x, NULL);

    fprintf(stderr, "Pull group  natoms  pbc atom  distance at start  reference at t=0\n");
    for (c = 0; c < pull->ncoord; c++)
    {
        t_pull_coord *pcrd;
        t_pull_group *pgrp0, *pgrp1;
        double        value;
        real          init = 0;

        pcrd  = &pull->coord[c];

        pgrp0 = &pull->group[pcrd->group[0]];
        pgrp1 = &pull->group[pcrd->group[1]];
        fprintf(stderr, "%8d  %8d  %8d\n",
                pcrd->group[0], pgrp0->nat, pgrp0->pbcatom+1);
        fprintf(stderr, "%8d  %8d  %8d ",
                pcrd->group[1], pgrp1->nat, pgrp1->pbcatom+1);

        if (pcrd->bStart)
        {
            init       = pcrd->init;
            pcrd->init = 0;
        }

        get_pull_coord_value(pull_work, c, &pbc, &value);
        fprintf(stderr, " %10.3f nm", value);

        if (pcrd->bStart)
        {
            pcrd->init = value + init;
        }
        fprintf(stderr, "     %10.3f nm\n", pcrd->init);
    }

    finish_pull(pull_work);
}
Esempio n. 2
0
void setStateDependentAwhParams(AwhParams *awhParams,
                                const pull_params_t *pull_params, pull_t *pull_work,
                                const matrix box,  int ePBC,
                                const t_grpopts *inputrecGroupOptions, warninp_t wi)
{
    /* The temperature is not really state depenendent but is not known
     * when read_awhParams is called (in get ir).
     * It is known first after do_index has been called in grompp.cpp.
     */
    if (inputrecGroupOptions->ref_t == NULL ||
        inputrecGroupOptions->ref_t[0] <= 0)
    {
        gmx_fatal(FARGS, "AWH biasing is only supported for temperatures > 0");
    }
    for (int i = 1; i < inputrecGroupOptions->ngtc; i++)
    {
        if (inputrecGroupOptions->ref_t[i] != inputrecGroupOptions->ref_t[0])
        {
            gmx_fatal(FARGS, "AWH biasing is currently only supported for identical temperatures for all temperature coupling groups");
        }
    }

    t_pbc          pbc;
    set_pbc(&pbc, ePBC, box);

    for (int k = 0; k < awhParams->numBias; k++)
    {
        AwhBiasParams *awhBiasParams = &awhParams->awhBiasParams[k];
        for (int d = 0; d < awhBiasParams->ndim; d++)
        {
            AwhDimParams *dimParams = &awhBiasParams->dimParams[d];

            /* The periodiciy of the AWH grid in certain cases depends on the simulation box */
            dimParams->period = get_pull_coord_period(pull_params, dimParams->coordIndex, box);

            /* The initial coordinate value, converted to external user units. */
            dimParams->coordValueInit =
                get_pull_coord_value(pull_work, dimParams->coordIndex, &pbc);

            t_pull_coord *pullCoord = &pull_params->coord[dimParams->coordIndex];
            dimParams->coordValueInit *= pull_conversion_factor_internal2userinput(pullCoord);
        }
    }
    checkInputConsistencyInterval(awhParams, wi);

    /* Register AWH as external potential with pull to check consistency. */
    Awh::registerAwhWithPull(*awhParams, pull_work);
}
Esempio n. 3
0
pull_t *set_pull_init(t_inputrec *ir, const gmx_mtop_t *mtop,
                      rvec *x, matrix box, real lambda,
                      warninp_t wi)
{
    pull_params_t *pull;
    pull_t        *pull_work;
    t_pbc          pbc;
    int            c;
    double         t_start;

    pull      = ir->pull;
    gmx::LocalAtomSetManager atomSets;
    pull_work = init_pull(nullptr, pull, ir, mtop, nullptr, &atomSets, lambda);
    auto                     mdAtoms = gmx::makeMDAtoms(nullptr, *mtop, *ir, false);
    auto                     md      = mdAtoms->mdatoms();
    atoms2md(mtop, ir, -1, nullptr, mtop->natoms, mdAtoms.get());
    if (ir->efep)
    {
        update_mdatoms(md, lambda);
    }

    set_pbc(&pbc, ir->ePBC, box);

    t_start = ir->init_t + ir->init_step*ir->delta_t;

    if (pull->bSetPbcRefToPrevStepCOM)
    {
        initPullComFromPrevStep(nullptr, pull_work, md, &pbc, x);
    }
    pull_calc_coms(nullptr, pull_work, md, &pbc, t_start, x, nullptr);

    for (int g = 0; g < pull->ngroup; g++)
    {
        bool groupObeysPbc =
            pullCheckPbcWithinGroup(*pull_work,
                                    gmx::arrayRefFromArray(reinterpret_cast<gmx::RVec *>(x),
                                                           mtop->natoms),
                                    pbc, g, c_pullGroupSmallGroupThreshold);
        if (!groupObeysPbc)
        {
            char buf[STRLEN];
            if (pull->group[g].pbcatom_input == 0)
            {
                sprintf(buf, "When the maximum distance from a pull group reference atom to other atoms in the "
                        "group is larger than %g times half the box size a centrally placed "
                        "atom should be chosen as pbcatom. Pull group %d is larger than that and does not have "
                        "a specific atom selected as reference atom.", c_pullGroupSmallGroupThreshold, g);
                warning_error(wi, buf);
            }
            else if (!pull->bSetPbcRefToPrevStepCOM)
            {
                sprintf(buf, "The maximum distance from the chosen PBC atom (%d) of pull group %d to other "
                        "atoms in the group is larger than %g times half the box size. "
                        "Set the pull-pbc-ref-prev-step-com option to yes.", pull->group[g].pbcatom + 1,
                        g, c_pullGroupSmallGroupThreshold);
                warning_error(wi, buf);
            }
        }
        if (groupObeysPbc)
        {
            groupObeysPbc =
                pullCheckPbcWithinGroup(*pull_work,
                                        gmx::arrayRefFromArray(reinterpret_cast<gmx::RVec *>(x),
                                                               mtop->natoms),
                                        pbc, g, c_pullGroupPbcMargin);
            if (!groupObeysPbc)
            {
                char buf[STRLEN];
                sprintf(buf,
                        "Pull group %d has atoms at a distance larger than %g times half the box size from the PBC atom (%d). "
                        "If atoms are or will more beyond half the box size from the PBC atom, the COM will be ill defined.",
                        g, c_pullGroupPbcMargin, pull->group[g].pbcatom + 1);
                set_warning_line(wi, nullptr, -1);
                warning(wi, buf);
            }
        }
    }

    fprintf(stderr, "Pull group  natoms  pbc atom  distance at start  reference at t=0\n");
    for (c = 0; c < pull->ncoord; c++)
    {
        t_pull_coord *pcrd;
        t_pull_group *pgrp0, *pgrp1;
        double        value;
        real          init = 0;

        pcrd  = &pull->coord[c];

        pgrp0 = &pull->group[pcrd->group[0]];
        pgrp1 = &pull->group[pcrd->group[1]];
        fprintf(stderr, "%8d  %8d  %8d\n",
                pcrd->group[0], pgrp0->nat, pgrp0->pbcatom+1);
        fprintf(stderr, "%8d  %8d  %8d ",
                pcrd->group[1], pgrp1->nat, pgrp1->pbcatom+1);

        if (pcrd->bStart)
        {
            init       = pcrd->init;
            pcrd->init = 0;
        }

        value  = get_pull_coord_value(pull_work, c, &pbc);

        value *= pull_conversion_factor_internal2userinput(pcrd);
        fprintf(stderr, " %10.3f %s", value, pull_coordinate_units(pcrd));

        if (pcrd->bStart)
        {
            pcrd->init = value + init;
        }

        if (pcrd->eGeom == epullgDIST)
        {
            if (pcrd->init < 0)
            {
                gmx_fatal(FARGS, "The initial pull distance (%g) needs to be non-negative with geometry %s. If you want a signed distance, use geometry %s instead.",
                          pcrd->init, EPULLGEOM(pcrd->eGeom), EPULLGEOM(epullgDIR));
            }

            /* TODO: With a positive init but a negative rate things could still
             * go wrong, but it might be fine if you don't pull too far.
             * We should give a warning or note when there is only one pull dim
             * active, since that is usually the problematic case when you should
             * be using direction. We will do this later, since an already planned
             * generalization of the pull code makes pull dim available here.
             */
        }
        else if (pcrd->eGeom == epullgANGLE || pcrd->eGeom == epullgANGLEAXIS)
        {
            if (pcrd->init < 0 || pcrd->init > 180)
            {
                gmx_fatal(FARGS,  "The initial pull reference angle (%g) is outside of the allowed range [0, 180] degrees.", pcrd->init);
            }
        }
        else if (pcrd->eGeom == epullgDIHEDRAL)
        {
            if (pcrd->init < -180 || pcrd->init > 180)
            {
                gmx_fatal(FARGS,  "The initial pull reference angle (%g) is outside of the allowed range [-180, 180] degrees.",
                          pcrd->init);
            }
        }


        fprintf(stderr, "     %10.3f %s\n", pcrd->init, pull_coordinate_units(pcrd));
    }

    return pull_work;
}
Esempio n. 4
0
pull_t *set_pull_init(t_inputrec *ir, const gmx_mtop_t *mtop,
                      rvec *x, matrix box, real lambda,
                      const gmx_output_env_t *oenv)
{
    pull_params_t *pull;
    pull_t        *pull_work;
    t_mdatoms     *md;
    t_pbc          pbc;
    int            c;
    double         t_start;

    pull      = ir->pull;
    pull_work = init_pull(NULL, pull, ir, 0, NULL, mtop, NULL, oenv, lambda, FALSE, 0);
    md        = init_mdatoms(NULL, mtop, ir->efep);
    atoms2md(mtop, ir, -1, NULL, mtop->natoms, md);
    if (ir->efep)
    {
        update_mdatoms(md, lambda);
    }

    set_pbc(&pbc, ir->ePBC, box);

    t_start = ir->init_t + ir->init_step*ir->delta_t;

    pull_calc_coms(NULL, pull_work, md, &pbc, t_start, x, NULL);

    fprintf(stderr, "Pull group  natoms  pbc atom  distance at start  reference at t=0\n");
    for (c = 0; c < pull->ncoord; c++)
    {
        t_pull_coord *pcrd;
        t_pull_group *pgrp0, *pgrp1;
        double        value;
        real          init = 0;

        pcrd  = &pull->coord[c];

        pgrp0 = &pull->group[pcrd->group[0]];
        pgrp1 = &pull->group[pcrd->group[1]];
        fprintf(stderr, "%8d  %8d  %8d\n",
                pcrd->group[0], pgrp0->nat, pgrp0->pbcatom+1);
        fprintf(stderr, "%8d  %8d  %8d ",
                pcrd->group[1], pgrp1->nat, pgrp1->pbcatom+1);

        if (pcrd->bStart)
        {
            init       = pcrd->init;
            pcrd->init = 0;
        }

        get_pull_coord_value(pull_work, c, &pbc, &value);

        value *= pull_conversion_factor_internal2userinput(pcrd);
        fprintf(stderr, " %10.3f %s", value, pull_coordinate_units(pcrd));

        if (pcrd->bStart)
        {
            pcrd->init = value + init;
        }

        if (pcrd->eGeom == epullgDIST)
        {
            if (pcrd->init < 0)
            {
                gmx_fatal(FARGS, "The initial pull distance (%g) needs to be non-negative with geometry %s. If you want a signed distance, use geometry %s instead.",
                          pcrd->init, EPULLGEOM(pcrd->eGeom), EPULLGEOM(epullgDIR));
            }

            /* TODO: With a positive init but a negative rate things could still
             * go wrong, but it might be fine if you don't pull too far.
             * We should give a warning or note when there is only one pull dim
             * active, since that is usually the problematic case when you should
             * be using direction. We will do this later, since an already planned
             * generalization of the pull code makes pull dim available here.
             */
        }
        else if (pcrd->eGeom == epullgANGLE || pcrd->eGeom == epullgANGLEAXIS)
        {
            if (pcrd->init < 0 || pcrd->init > 180)
            {
                gmx_fatal(FARGS,  "The initial pull reference angle (%g) is outside of the allowed range [0, 180] degrees.", pcrd->init);
            }
        }
        else if (pcrd->eGeom == epullgDIHEDRAL)
        {
            if (pcrd->init < -180 || pcrd->init > 180)
            {
                gmx_fatal(FARGS,  "The initial pull reference angle (%g) is outside of the allowed range [-180, 180] degrees.",
                          pcrd->init);
            }
        }


        fprintf(stderr, "     %10.3f %s\n", pcrd->init, pull_coordinate_units(pcrd));
    }

    return pull_work;
}