Exemple #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       g,j,m;
    dvec      dev;
    double    ndr,invdr;
    real      k,dkdl;
    t_pullgrp *pgrp;
    
    /* loop over the groups that are being pulled */
    *V    = 0;
    *dVdl = 0;
    for(g=1; g<1+pull->ngrp; g++)
    {
        pgrp = &pull->grp[g];
        get_pullgrp_distance(pull,pbc,g,t,pgrp->dr,dev);
        
        k    = (1.0 - lambda)*pgrp->k + lambda*pgrp->kB;
        dkdl = pgrp->kB - pgrp->k;
        
        switch (pull->eGeom)
        {
        case epullgDIST:
            ndr   = dnorm(pgrp->dr);
            invdr = 1/ndr;
            if (ePull == epullUMBRELLA)
            {
                pgrp->f_scal  =       -k*dev[0];
                *V           += 0.5*   k*dsqr(dev[0]);
                *dVdl        += 0.5*dkdl*dsqr(dev[0]);
            }
            else
            {
                pgrp->f_scal  =   -k;
                *V           +=    k*ndr;
                *dVdl        += dkdl*ndr;
            }
            for(m=0; m<DIM; m++)
            {
                pgrp->f[m]    = pgrp->f_scal*pgrp->dr[m]*invdr;
            }
            break;
        case epullgDIR:
        case epullgDIRPBC:
        case epullgCYL:
            if (ePull == epullUMBRELLA)
            {
                pgrp->f_scal  =       -k*dev[0];
                *V           += 0.5*   k*dsqr(dev[0]);
                *dVdl        += 0.5*dkdl*dsqr(dev[0]);
            }
            else
            {
                ndr = 0;
                for(m=0; m<DIM; m++)
                {
                    ndr += pgrp->vec[m]*pgrp->dr[m];
                }
                pgrp->f_scal  =   -k;
                *V           +=    k*ndr;
                *dVdl        += dkdl*ndr;
            }
            for(m=0; m<DIM; m++)
            {
                pgrp->f[m]    = pgrp->f_scal*pgrp->vec[m];
            }
            break;
        case epullgPOS:
            for(m=0; m<DIM; m++)
            {
                if (ePull == epullUMBRELLA)
                {
                    pgrp->f[m]  =       -k*dev[m];
                    *V         += 0.5*   k*dsqr(dev[m]);
                    *dVdl      += 0.5*dkdl*dsqr(dev[m]);
                }
                else
                {
                    pgrp->f[m]  =   -k*pull->dim[m];
                    *V         +=    k*pgrp->dr[m]*pull->dim[m];
                    *dVdl      += dkdl*pgrp->dr[m]*pull->dim[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*pgrp->f[j]*pgrp->dr[m];
                }
            }
        }
    }
}
Exemple #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_pullgrp *pgrp;
    t_pbc      pbc;
    int        ndim, g, m;
    double     t_start, tinvrate;
    rvec       init;
    dvec       dr, 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, 0, mtop->natoms, md);
    if (ir->efep)
    {
        update_mdatoms(md, lambda);
    }
    pull = ir->pull;
    if (pull->eGeom == epullgPOS)
    {
        ndim = 3;
    }
    else
    {
        ndim = 1;
    }

    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 (g = 0; g < pull->ngrp+1; g++)
    {
        pgrp = &pull->grp[g];
        fprintf(stderr, "%8d  %8d  %8d ", g, pgrp->nat, pgrp->pbcatom+1);
        copy_rvec(pgrp->init, init);
        clear_rvec(pgrp->init);
        if (g > 0)
        {
            if (pgrp->rate == 0)
            {
                tinvrate = 0;
            }
            else
            {
                tinvrate = t_start/pgrp->rate;
            }
            get_pullgrp_distance(pull, &pbc, g, 0, dr, dev);
            for (m = 0; m < DIM; m++)
            {
                if (m < ndim)
                {
                    fprintf(stderr, " %6.3f", dev[m]);
                }
                else
                {
                    fprintf(stderr, "       ");
                }
            }
            fprintf(stderr, " ");
            for (m = 0; m < DIM; m++)
            {
                if (bStart)
                {
                    pgrp->init[m] = init[m] + dev[m]
                        - tinvrate*(pull->eGeom == epullgPOS ? pgrp->vec[m] : 1);
                }
                else
                {
                    pgrp->init[m] = init[m];
                }
                if (m < ndim)
                {
                    fprintf(stderr, " %6.3f", pgrp->init[m]);
                }
                else
                {
                    fprintf(stderr, "       ");
                }
            }
        }
        fprintf(stderr, "\n");
    }
}