Пример #1
0
static real ektrans(rvec v[], real mass[], int isize, int index[])
{
    dvec   mvcom;
    double mtot;
    int    i, j, d;

    clear_dvec(mvcom);
    mtot = 0;
    for (i = 0; i < isize; i++)
    {
        j = index[i];
        for (d = 0; d < DIM; d++)
        {
            mvcom[d] += mass[j]*v[j][d];
        }
        mtot += mass[j];
    }

    return dnorm2(mvcom)/(mtot*2);
}
Пример #2
0
static void init_pull_coord(t_pull_coord *pcrd, int coord_index_for_output,
                            char *dim_buf,
                            const char *origin_buf, const char *vec_buf,
                            warninp_t wi)
{
    int    m;
    dvec   origin, vec;
    char   buf[STRLEN];

    if (pcrd->eType == epullCONSTRAINT && (pcrd->eGeom == epullgCYL ||
                                           pcrd->eGeom == epullgDIRRELATIVE ||
                                           pcrd->eGeom == epullgANGLE ||
                                           pcrd->eGeom == epullgANGLEAXIS ||
                                           pcrd->eGeom == epullgDIHEDRAL))
    {
        gmx_fatal(FARGS, "Pulling of type %s can not be combined with geometry %s. Consider using pull type %s.",
                  epull_names[pcrd->eType],
                  epullg_names[pcrd->eGeom],
                  epull_names[epullUMBRELLA]);
    }

    if (pcrd->eType == epullEXTERNAL)
    {
        if (pcrd->externalPotentialProvider[0] == '\0')
        {
            sprintf(buf, "The use of pull type '%s' for pull coordinate %d requires that the name of the module providing the potential external is set with the option %s%d%s",
                    epull_names[pcrd->eType], coord_index_for_output,
                    "pull-coord", coord_index_for_output, "-potential-provider");
            warning_error(wi, buf);
        }

        if (pcrd->rate != 0)
        {
            sprintf(buf, "The use of pull type '%s' for pull coordinate %d requires that the pull rate is zero",
                    epull_names[pcrd->eType], coord_index_for_output);
            warning_error(wi, buf);
        }

        if (pcrd->eGeom == epullgCYL)
        {
            /* Warn the user of a PBC restriction, caused by the fact that
             * there is no reference value with an external pull potential.
             */
            sprintf(buf, "With pull type '%s' and geometry '%s', the distance component along the cylinder axis between atoms in the cylinder group and the COM of the pull group should be smaller than half the box length",
                    epull_names[pcrd->eType], epullg_names[pcrd->eGeom]);
            warning_note(wi, buf);
        }
    }

    process_pull_dim(dim_buf, pcrd->dim, pcrd);

    string2dvec(origin_buf, origin);
    if (pcrd->group[0] != 0 && dnorm(origin) > 0)
    {
        gmx_fatal(FARGS, "The pull origin can only be set with an absolute reference");
    }

    /* Check the given initial reference value and warn for dangerous values */
    if (pcrd->eGeom == epullgDIST)
    {
        if (pcrd->bStart && pcrd->init < 0)
        {
            sprintf(buf, "The initial reference distance set by pull-coord-init is set to a negative value (%g) with geometry %s while distances need to be non-negative. "
                    "This may work, since you have set pull-coord-start to 'yes' which modifies this value, but only for certain starting distances. "
                    "If this is a mistake you may want to use geometry %s instead.",
                    pcrd->init, EPULLGEOM(pcrd->eGeom), EPULLGEOM(epullgDIR));
            warning(wi, buf);
        }
    }
    else if (pcrd->eGeom == epullgANGLE || pcrd->eGeom == epullgANGLEAXIS)
    {
        if (pcrd->bStart && (pcrd->init < 0 || pcrd->init > 180))
        {
            /* This value of pcrd->init may be ok depending on pcrd->bStart which modifies pcrd->init later on */
            sprintf(buf, "The initial reference angle set by pull-coord-init (%g) is outside of the allowed range [0, 180] degrees for geometry (%s). "
                    "This may work, since you have set pull-coord-start to 'yes' which modifies this value, but only for certain starting angles.",
                    pcrd->init, EPULLGEOM(pcrd->eGeom));
            warning(wi, buf);
        }
    }
    else if (pcrd->eGeom == epullgDIHEDRAL)
    {
        if (pcrd->bStart && (pcrd->init < -180 || pcrd->init > 180))
        {
            sprintf(buf, "The initial reference angle set by pull-coord-init (%g) is outside of the allowed range [-180, 180] degrees for geometry (%s). "
                    "This may work, since you have set pull-coord-start to 'yes' which modifies this value, but only for certain starting angles.",
                    pcrd->init, EPULLGEOM(pcrd->eGeom));
            warning(wi, buf);
        }
    }

    /* Check and set the pull vector */
    clear_dvec(vec);
    string2dvec(vec_buf, vec);

    if (pcrd->eGeom == epullgDIR || pcrd->eGeom == epullgCYL || pcrd->eGeom == epullgDIRPBC || pcrd->eGeom == epullgANGLEAXIS)
    {
        if (dnorm2(vec) == 0)
        {
            gmx_fatal(FARGS, "With pull geometry %s the pull vector can not be 0,0,0",
                      epullg_names[pcrd->eGeom]);
        }
        for (int d = 0; d < DIM; d++)
        {
            if (vec[d] != 0 && pcrd->dim[d] == 0)
            {
                gmx_fatal(FARGS, "pull-coord-vec has non-zero %c-component while pull_dim for the %c-dimension is set to N", 'x'+d, 'x'+d);
            }
        }

        /* Normalize the direction vector */
        dsvmul(1/dnorm(vec), vec, vec);
    }
    else /* This case is for are all the geometries where the pull vector is not used */
    {
        if (dnorm2(vec) > 0)
        {
            sprintf(buf, "A pull vector is given (%g  %g  %g) but will not be used with geometry %s. If you really want to use this "
                    "vector, consider using geometry %s instead.",
                    vec[0], vec[1], vec[2], EPULLGEOM(pcrd->eGeom),
                    pcrd->eGeom == epullgANGLE ? EPULLGEOM(epullgANGLEAXIS) : EPULLGEOM(epullgDIR));
            warning(wi, buf);
        }
    }
    for (m = 0; m < DIM; m++)
    {
        pcrd->origin[m] = origin[m];
        pcrd->vec[m]    = vec[m];
    }
}
Пример #3
0
static void init_pull_coord(t_pull_coord *pcrd,
                            char *dim_buf,
                            const char *origin_buf, const char *vec_buf,
                            warninp_t wi)
{
    int    m;
    dvec   origin, vec;
    char   buf[STRLEN];

    if (pcrd->eType == epullCONSTRAINT && (pcrd->eGeom == epullgCYL ||
                                           pcrd->eGeom == epullgDIRRELATIVE))
    {
        gmx_fatal(FARGS, "Pulling of type %s can not be combined with geometry %s. Consider using pull type %s.",
                  epull_names[pcrd->eType],
                  epullg_names[pcrd->eGeom],
                  epull_names[epullUMBRELLA]);
    }

    process_pull_dim(dim_buf, pcrd->dim);

    string2dvec(origin_buf, origin);
    if (pcrd->group[0] != 0 && dnorm(origin) > 0)
    {
        gmx_fatal(FARGS, "The pull origin can only be set with an absolute reference");
    }

    /* Check and set the pull vector */
    clear_dvec(vec);
    if (pcrd->eGeom == epullgDIST)
    {
        if (pcrd->init < 0)
        {
            sprintf(buf, "The initial pull distance is negative with geometry %s, while a distance can not be negative. Use geometry %s instead.",
                    EPULLGEOM(pcrd->eGeom), EPULLGEOM(epullgDIR));
            warning_error(wi, buf);
        }
        /* 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 != epullgDIRRELATIVE)
    {
        string2dvec(vec_buf, vec);
        if (dnorm2(vec) == 0)
        {
            gmx_fatal(FARGS, "With pull geometry %s the pull vector can not be 0,0,0",
                      epullg_names[pcrd->eGeom]);
        }
        if (pcrd->eGeom == epullgDIR || pcrd->eGeom == epullgCYL)
        {
            /* Normalize the direction vector */
            dsvmul(1/dnorm(vec), vec, vec);
        }
    }
    for (m = 0; m < DIM; m++)
    {
        pcrd->origin[m] = origin[m];
        pcrd->vec[m]    = vec[m];
    }
}