/* 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]; } } } } }
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); } }