Esempio n. 1
0
/* Pulling with a harmonic umbrella potential or constant force */
static void do_pull_pot(int ePull,
                        t_pull *pull, t_pbc *pbc, double t, real lambda,
                        real *V, tensor vir, real *dVdl)
{
    int           c, j, m;
    double        dev, ndr, invdr;
    real          k, dkdl;
    t_pull_coord *pcrd;

    /* loop over the pull coordinates */
    *V    = 0;
    *dVdl = 0;
    for (c = 0; c < pull->ncoord; c++)
    {
        pcrd = &pull->coord[c];

        get_pull_coord_distance(pull, c, pbc, t, pcrd->dr, &dev);

        k    = (1.0 - lambda)*pcrd->k + lambda*pcrd->kB;
        dkdl = pcrd->kB - pcrd->k;

        switch (pull->eGeom)
        {
            case epullgDIST:
                ndr   = dnorm(pcrd->dr);
                invdr = 1/ndr;
                if (ePull == epullUMBRELLA)
                {
                    pcrd->f_scal  =       -k*dev;
                    *V           += 0.5*   k*dsqr(dev);
                    *dVdl        += 0.5*dkdl*dsqr(dev);
                }
                else
                {
                    pcrd->f_scal  =   -k;
                    *V           +=    k*ndr;
                    *dVdl        += dkdl*ndr;
                }
                for (m = 0; m < DIM; m++)
                {
                    pcrd->f[m]    = pcrd->f_scal*pcrd->dr[m]*invdr;
                }
                break;
            case epullgDIR:
            case epullgDIRPBC:
            case epullgCYL:
                if (ePull == epullUMBRELLA)
                {
                    pcrd->f_scal  =       -k*dev;
                    *V           += 0.5*   k*dsqr(dev);
                    *dVdl        += 0.5*dkdl*dsqr(dev);
                }
                else
                {
                    ndr = 0;
                    for (m = 0; m < DIM; m++)
                    {
                        ndr += pcrd->vec[m]*pcrd->dr[m];
                    }
                    pcrd->f_scal  =   -k;
                    *V           +=    k*ndr;
                    *dVdl        += dkdl*ndr;
                }
                for (m = 0; m < DIM; m++)
                {
                    pcrd->f[m]    = pcrd->f_scal*pcrd->vec[m];
                }
                break;
        }

        if (vir)
        {
            /* Add the pull contribution to the virial */
            for (j = 0; j < DIM; j++)
            {
                for (m = 0; m < DIM; m++)
                {
                    vir[j][m] -= 0.5*pcrd->f[j]*pcrd->dr[m];
                }
            }
        }
    }
}
Esempio n. 2
0
void set_pull_init(t_inputrec *ir, gmx_mtop_t *mtop, rvec *x, matrix box, real lambda,
                   const output_env_t oenv, gmx_bool bStart)
{
    t_mdatoms    *md;
    t_pull       *pull;
    t_pull_coord *pcrd;
    t_pull_group *pgrp0, *pgrp1;
    t_pbc         pbc;
    int           c, m;
    double        t_start, tinvrate;
    real          init;
    dvec          dr;
    double        dev;

    init_pull(NULL, 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);
    }
    pull = ir->pull;

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

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

    pull_calc_coms(NULL, pull, 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++)
    {
        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);

        init       = pcrd->init;
        pcrd->init = 0;

        if (pcrd->rate == 0)
        {
            tinvrate = 0;
        }
        else
        {
            tinvrate = t_start/pcrd->rate;
        }
        get_pull_coord_distance(pull, c, &pbc, 0, dr, &dev);
        fprintf(stderr, " %6.3f ", dev);

        if (bStart)
        {
            pcrd->init = init + dev - tinvrate;
        }
        else
        {
            pcrd->init = init;
        }
        fprintf(stderr, " %6.3f\n", pcrd->init);
    }
}