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); } }
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; }