2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2004, The GROMACS development team.
6 * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
7 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8 * and including many others, as listed in the AUTHORS file in the
9 * top-level source directory and at http://www.gromacs.org.
11 * GROMACS is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 2.1
14 * of the License, or (at your option) any later version.
16 * GROMACS is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with GROMACS; if not, see
23 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 * If you want to redistribute modifications to GROMACS, please
27 * consider that scientific software is very special. Version
28 * control is crucial - bugs must be traceable. We will be happy to
29 * consider code for inclusion in the official distribution, but
30 * derived work must not be called official GROMACS. Details are found
31 * in the README & COPYING files - if they are missing, get the
32 * official version at http://www.gromacs.org.
34 * To help us fund GROMACS development, we humbly ask that you cite
35 * the research papers on the package. Check out http://www.gromacs.org.
51 #include "gromacs/fileio/filenm.h"
52 #include "gromacs/fileio/gmxfio.h"
53 #include "gromacs/fileio/xvgr.h"
54 #include "gromacs/legacyheaders/copyrite.h"
55 #include "gromacs/legacyheaders/gmx_ga2la.h"
56 #include "gromacs/legacyheaders/macros.h"
57 #include "gromacs/legacyheaders/mdrun.h"
58 #include "gromacs/legacyheaders/names.h"
59 #include "gromacs/legacyheaders/network.h"
60 #include "gromacs/legacyheaders/typedefs.h"
61 #include "gromacs/legacyheaders/types/commrec.h"
62 #include "gromacs/math/vec.h"
63 #include "gromacs/pbcutil/pbc.h"
64 #include "gromacs/pulling/pull_internal.h"
65 #include "gromacs/topology/mtop_util.h"
66 #include "gromacs/utility/futil.h"
67 #include "gromacs/utility/gmxassert.h"
68 #include "gromacs/utility/smalloc.h"
70 static void pull_print_group_x(FILE *out, ivec dim,
71 const pull_group_work_t *pgrp)
75 for (m = 0; m < DIM; m++)
79 fprintf(out, "\t%g", pgrp->x[m]);
84 static void pull_print_coord_dr(FILE *out, const pull_coord_work_t *pcrd,
85 gmx_bool bPrintRefValue,
86 gmx_bool bPrintComponents)
88 fprintf(out, "\t%g", pcrd->value);
92 fprintf(out, "\t%g", pcrd->value_ref);
99 for (m = 0; m < DIM; m++)
101 if (pcrd->params.dim[m])
103 fprintf(out, "\t%g", pcrd->dr[m]);
109 static void pull_print_x(FILE *out, struct pull_t *pull, double t)
113 fprintf(out, "%.4f", t);
115 for (c = 0; c < pull->ncoord; c++)
117 pull_coord_work_t *pcrd;
119 pcrd = &pull->coord[c];
121 if (pull->params.bPrintCOM1)
123 if (pcrd->params.eGeom == epullgCYL)
125 pull_print_group_x(out, pcrd->params.dim, &pull->dyna[c]);
129 pull_print_group_x(out, pcrd->params.dim,
130 &pull->group[pcrd->params.group[0]]);
133 if (pull->params.bPrintCOM2)
135 pull_print_group_x(out, pcrd->params.dim,
136 &pull->group[pcrd->params.group[1]]);
138 pull_print_coord_dr(out, pcrd,
139 pull->params.bPrintRefValue,
140 pull->params.bPrintComp);
145 static void pull_print_f(FILE *out, struct pull_t *pull, double t)
149 fprintf(out, "%.4f", t);
151 for (c = 0; c < pull->ncoord; c++)
153 fprintf(out, "\t%g", pull->coord[c].f_scal);
158 void pull_print_output(struct pull_t *pull, gmx_int64_t step, double time)
160 if ((pull->params.nstxout != 0) && (step % pull->params.nstxout == 0))
162 pull_print_x(pull->out_x, pull, time);
165 if ((pull->params.nstfout != 0) && (step % pull->params.nstfout == 0))
167 pull_print_f(pull->out_f, pull, time);
171 static FILE *open_pull_out(const char *fn, struct pull_t *pull, const output_env_t oenv,
172 gmx_bool bCoord, unsigned long Flags)
176 char **setname, buf[10];
178 if (Flags & MD_APPENDFILES)
180 fp = gmx_fio_fopen(fn, "a+");
184 fp = gmx_fio_fopen(fn, "w+");
187 xvgr_header(fp, "Pull COM", "Time (ps)", "Position (nm)",
192 xvgr_header(fp, "Pull force", "Time (ps)", "Force (kJ/mol/nm)",
196 /* With default mdp options only the actual distance is printed,
197 * but optionally 2 COMs, the reference distance and distance
198 * components can also be printed.
200 snew(setname, pull->ncoord*(DIM + DIM + 1 + 1 + DIM));
202 for (c = 0; c < pull->ncoord; c++)
206 /* The order of this legend should match the order of printing
207 * the data in print_pull_x above.
210 if (pull->params.bPrintCOM1)
212 /* Legend for reference group position */
213 for (m = 0; m < DIM; m++)
215 if (pull->coord[c].params.dim[m])
217 sprintf(buf, "%d %s%d%c", c+1, "c", 1, 'X'+m);
218 setname[nsets] = gmx_strdup(buf);
223 if (pull->params.bPrintCOM2)
225 /* Legend for reference group position */
226 for (m = 0; m < DIM; m++)
228 if (pull->coord[c].params.dim[m])
230 sprintf(buf, "%d %s%d%c", c+1, "c", 2, 'X'+m);
231 setname[nsets] = gmx_strdup(buf);
236 /* The pull coord distance */
237 sprintf(buf, "%d", c+1);
238 setname[nsets] = gmx_strdup(buf);
240 if (pull->params.bPrintRefValue)
242 sprintf(buf, "%c%d", 'r', c+1);
243 setname[nsets] = gmx_strdup(buf);
246 if (pull->params.bPrintComp)
248 /* The pull coord distance components */
249 for (m = 0; m < DIM; m++)
251 if (pull->coord[c].params.dim[m])
253 sprintf(buf, "%d %s%c", c+1, "d", 'X'+m);
254 setname[nsets] = gmx_strdup(buf);
262 /* For the pull force we always only use one scalar */
263 sprintf(buf, "%d", c+1);
264 setname[nsets] = gmx_strdup(buf);
270 xvgr_legend(fp, nsets, (const char**)setname, oenv);
272 for (c = 0; c < nsets; c++)
282 /* Apply forces in a mass weighted fashion */
283 static void apply_forces_grp(const pull_group_work_t *pgrp,
285 const dvec f_pull, int sign, rvec *f)
288 double wmass, inv_wm;
290 inv_wm = pgrp->mwscale;
292 if (pgrp->params.nat == 1 && pgrp->nat_loc == 1)
294 /* Only one atom and our rank has this atom: we can skip
295 * the mass weighting, which means that this code also works
296 * for mass=0, e.g. with a virtual site.
298 for (m = 0; m < DIM; m++)
300 f[pgrp->ind_loc[0]][m] += sign*f_pull[m];
305 for (i = 0; i < pgrp->nat_loc; i++)
307 ii = pgrp->ind_loc[i];
308 wmass = md->massT[ii];
309 if (pgrp->weight_loc)
311 wmass *= pgrp->weight_loc[i];
314 for (m = 0; m < DIM; m++)
316 f[ii][m] += sign * wmass * f_pull[m] * inv_wm;
322 /* Apply forces in a mass weighted fashion to a cylinder group */
323 static void apply_forces_cyl_grp(const pull_group_work_t *pgrp,
326 const dvec f_pull, double f_scal,
330 double mass, weight, inv_wm, dv_com;
332 inv_wm = pgrp->mwscale;
334 for (i = 0; i < pgrp->nat_loc; i++)
336 ii = pgrp->ind_loc[i];
337 mass = md->massT[ii];
338 weight = pgrp->weight_loc[i];
339 /* The stored axial distance from the cylinder center (dv) needs
340 * to be corrected for an offset (dv_corr), which was unknown when
343 dv_com = pgrp->dv[i] + dv_corr;
345 /* Here we not only add the pull force working along vec (f_pull),
346 * but also a radial component, due to the dependence of the weights
347 * on the radial distance.
349 for (m = 0; m < DIM; m++)
351 f[ii][m] += sign*inv_wm*(mass*weight*f_pull[m] +
352 pgrp->mdw[i][m]*dv_com*f_scal);
357 /* Apply torque forces in a mass weighted fashion to the groups that define
358 * the pull vector direction for pull coordinate pcrd.
360 static void apply_forces_vec_torque(const struct pull_t *pull,
361 const pull_coord_work_t *pcrd,
369 /* The component inpr along the pull vector is accounted for in the usual
370 * way. Here we account for the component perpendicular to vec.
373 for (m = 0; m < DIM; m++)
375 inpr += pcrd->dr[m]*pcrd->vec[m];
377 /* The torque force works along the component of the distance vector
378 * of between the two "usual" pull groups that is perpendicular to
379 * the pull vector. The magnitude of this force is the "usual" scale force
380 * multiplied with the ratio of the distance between the two "usual" pull
381 * groups and the distance between the two groups that define the vector.
383 for (m = 0; m < DIM; m++)
385 f_perp[m] = (pcrd->dr[m] - inpr*pcrd->vec[m])/pcrd->vec_len*pcrd->f_scal;
388 /* Apply the force to the groups defining the vector using opposite signs */
389 apply_forces_grp(&pull->group[pcrd->params.group[2]], md, f_perp, -1, f);
390 apply_forces_grp(&pull->group[pcrd->params.group[3]], md, f_perp, 1, f);
393 /* Apply forces in a mass weighted fashion */
394 static void apply_forces(struct pull_t * pull, t_mdatoms * md, rvec *f)
398 for (c = 0; c < pull->ncoord; c++)
400 const pull_coord_work_t *pcrd;
402 pcrd = &pull->coord[c];
404 if (pcrd->params.eGeom == epullgCYL)
409 apply_forces_cyl_grp(&pull->dyna[c], pcrd->cyl_dev, md,
410 pcrd->f, pcrd->f_scal, -1, f);
412 /* Sum the force along the vector and the radial force */
413 for (m = 0; m < DIM; m++)
415 f_tot[m] = pcrd->f[m] + pcrd->f_scal*pcrd->ffrad[m];
417 apply_forces_grp(&pull->group[pcrd->params.group[1]], md, f_tot, 1, f);
421 if (pcrd->params.eGeom == epullgDIRRELATIVE)
423 /* We need to apply the torque forces to the pull groups
424 * that define the pull vector.
426 apply_forces_vec_torque(pull, pcrd, md, f);
429 if (pull->group[pcrd->params.group[0]].params.nat > 0)
431 apply_forces_grp(&pull->group[pcrd->params.group[0]], md, pcrd->f, -1, f);
433 apply_forces_grp(&pull->group[pcrd->params.group[1]], md, pcrd->f, 1, f);
438 static double max_pull_distance2(const pull_coord_work_t *pcrd,
444 max_d2 = GMX_DOUBLE_MAX;
446 for (m = 0; m < pbc->ndim_ePBC; m++)
448 if (pcrd->params.dim[m] != 0)
450 max_d2 = std::min(max_d2, static_cast<double>(norm2(pbc->box[m])));
457 /* This function returns the distance based on coordinates xg and xref.
458 * Note that the pull coordinate struct pcrd is not modified.
460 static void low_get_pull_coord_dr(const struct pull_t *pull,
461 const pull_coord_work_t *pcrd,
463 dvec xg, dvec xref, double max_dist2,
466 const pull_group_work_t *pgrp0;
468 dvec xrefr, dref = {0, 0, 0};
471 pgrp0 = &pull->group[pcrd->params.group[0]];
473 /* Only the first group can be an absolute reference, in that case nat=0 */
474 if (pgrp0->params.nat == 0)
476 for (m = 0; m < DIM; m++)
478 xref[m] = pcrd->params.origin[m];
482 copy_dvec(xref, xrefr);
484 if (pcrd->params.eGeom == epullgDIRPBC)
486 for (m = 0; m < DIM; m++)
488 dref[m] = pcrd->value_ref*pcrd->vec[m];
490 /* Add the reference position, so we use the correct periodic image */
491 dvec_inc(xrefr, dref);
494 pbc_dx_d(pbc, xg, xrefr, dr);
496 for (m = 0; m < DIM; m++)
498 dr[m] *= pcrd->params.dim[m];
501 if (max_dist2 >= 0 && dr2 > 0.98*0.98*max_dist2)
503 gmx_fatal(FARGS, "Distance between pull groups %d and %d (%f nm) is larger than 0.49 times the box size (%f).\nYou might want to consider using \"pull-geometry = direction-periodic\" instead.\n",
504 pcrd->params.group[0], pcrd->params.group[1],
505 sqrt(dr2), sqrt(max_dist2));
508 if (pcrd->params.eGeom == epullgDIRPBC)
514 /* This function returns the distance based on the contents of the pull struct.
515 * pull->coord[coord_ind].dr, and potentially vector, are updated.
517 static void get_pull_coord_dr(struct pull_t *pull,
522 pull_coord_work_t *pcrd;
524 pcrd = &pull->coord[coord_ind];
526 if (pcrd->params.eGeom == epullgDIRPBC)
532 md2 = max_pull_distance2(pcrd, pbc);
535 if (pcrd->params.eGeom == epullgDIRRELATIVE)
537 /* We need to determine the pull vector */
538 const pull_group_work_t *pgrp2, *pgrp3;
542 pgrp2 = &pull->group[pcrd->params.group[2]];
543 pgrp3 = &pull->group[pcrd->params.group[3]];
545 pbc_dx_d(pbc, pgrp3->x, pgrp2->x, vec);
547 for (m = 0; m < DIM; m++)
549 vec[m] *= pcrd->params.dim[m];
551 pcrd->vec_len = dnorm(vec);
552 for (m = 0; m < DIM; m++)
554 pcrd->vec[m] = vec[m]/pcrd->vec_len;
558 fprintf(debug, "pull coord %d vector: %6.3f %6.3f %6.3f normalized: %6.3f %6.3f %6.3f\n",
560 vec[XX], vec[YY], vec[ZZ],
561 pcrd->vec[XX], pcrd->vec[YY], pcrd->vec[ZZ]);
565 low_get_pull_coord_dr(pull, pcrd, pbc,
566 pull->group[pcrd->params.group[1]].x,
567 pcrd->params.eGeom == epullgCYL ? pull->dyna[coord_ind].x : pull->group[pcrd->params.group[0]].x,
572 static void update_pull_coord_reference_value(pull_coord_work_t *pcrd, double t)
574 /* With zero rate the reference value is set initially and doesn't change */
575 if (pcrd->params.rate != 0)
577 pcrd->value_ref = pcrd->params.init + pcrd->params.rate*t;
581 /* Calculates pull->coord[coord_ind].value.
582 * This function also updates pull->coord[coord_ind].dr.
584 static void get_pull_coord_distance(struct pull_t *pull,
588 pull_coord_work_t *pcrd;
591 pcrd = &pull->coord[coord_ind];
593 get_pull_coord_dr(pull, coord_ind, pbc);
595 switch (pcrd->params.eGeom)
598 /* Pull along the vector between the com's */
599 pcrd->value = dnorm(pcrd->dr);
603 case epullgDIRRELATIVE:
607 for (m = 0; m < DIM; m++)
609 pcrd->value += pcrd->vec[m]*pcrd->dr[m];
615 /* Returns the deviation from the reference value.
616 * Updates pull->coord[coord_ind].dr, .value and .value_ref.
618 static double get_pull_coord_deviation(struct pull_t *pull,
623 static gmx_bool bWarned = FALSE; /* TODO: this should be fixed for thread-safety,
624 but is fairly benign */
625 pull_coord_work_t *pcrd;
628 pcrd = &pull->coord[coord_ind];
630 get_pull_coord_distance(pull, coord_ind, pbc);
632 update_pull_coord_reference_value(pcrd, t);
634 switch (pcrd->params.eGeom)
637 /* Pull along the vector between the com's */
638 if (pcrd->value_ref < 0 && !bWarned)
640 fprintf(stderr, "\nPull reference distance for coordinate %d is negative (%f)\n", coord_ind+1, pcrd->value_ref);
643 if (pcrd->value == 0)
645 /* With no vector we can not determine the direction for the force,
646 * so we set the force to zero.
652 /* Determine the deviation */
653 dev = pcrd->value - pcrd->value_ref;
658 case epullgDIRRELATIVE:
661 dev = pcrd->value - pcrd->value_ref;
668 void get_pull_coord_value(struct pull_t *pull,
673 get_pull_coord_distance(pull, coord_ind, pbc);
675 *value = pull->coord[coord_ind].value;
678 void clear_pull_forces(struct pull_t *pull)
682 /* Zeroing the forces is only required for constraint pulling.
683 * It can happen that multiple constraint steps need to be applied
684 * and therefore the constraint forces need to be accumulated.
686 for (i = 0; i < pull->ncoord; i++)
688 clear_dvec(pull->coord[i].f);
689 pull->coord[i].f_scal = 0;
693 /* Apply constraint using SHAKE */
694 static void do_constraint(struct pull_t *pull, t_pbc *pbc,
696 gmx_bool bMaster, tensor vir,
700 dvec *r_ij; /* x[i] com of i in prev. step. Obeys constr. -> r_ij[i] */
701 dvec unc_ij; /* xp[i] com of i this step, before constr. -> unc_ij */
702 dvec *rnew; /* current 'new' positions of the groups */
703 double *dr_tot; /* the total update of the coords */
706 double lambda, rm, invdt = 0;
707 gmx_bool bConverged_all, bConverged = FALSE;
708 int niter = 0, g, c, ii, j, m, max_iter = 100;
712 snew(r_ij, pull->ncoord);
713 snew(dr_tot, pull->ncoord);
715 snew(rnew, pull->ngroup);
717 /* copy the current unconstrained positions for use in iterations. We
718 iterate until rinew[i] and rjnew[j] obey the constraints. Then
719 rinew - pull.x_unc[i] is the correction dr to group i */
720 for (g = 0; g < pull->ngroup; g++)
722 copy_dvec(pull->group[g].xp, rnew[g]);
725 /* Determine the constraint directions from the old positions */
726 for (c = 0; c < pull->ncoord; c++)
728 pull_coord_work_t *pcrd;
730 pcrd = &pull->coord[c];
732 if (pcrd->params.eType != epullCONSTRAINT)
737 /* Note that get_pull_coord_distance also sets pcrd->dr and pcrd->value.
738 * We don't modify dr and value anymore, so these values are also used
741 get_pull_coord_distance(pull, c, pbc);
745 fprintf(debug, "Pull coord %d dr %f %f %f\n",
746 c, pcrd->dr[XX], pcrd->dr[YY], pcrd->dr[ZZ]);
749 if (pcrd->params.eGeom == epullgDIR ||
750 pcrd->params.eGeom == epullgDIRPBC)
752 /* Select the component along vec */
754 for (m = 0; m < DIM; m++)
756 a += pcrd->vec[m]*pcrd->dr[m];
758 for (m = 0; m < DIM; m++)
760 r_ij[c][m] = a*pcrd->vec[m];
765 copy_dvec(pcrd->dr, r_ij[c]);
768 if (dnorm2(r_ij[c]) == 0)
770 gmx_fatal(FARGS, "Distance for pull coordinate %d is zero with constraint pulling, which is not allowed.", c + 1);
774 bConverged_all = FALSE;
775 while (!bConverged_all && niter < max_iter)
777 bConverged_all = TRUE;
779 /* loop over all constraints */
780 for (c = 0; c < pull->ncoord; c++)
782 pull_coord_work_t *pcrd;
783 pull_group_work_t *pgrp0, *pgrp1;
786 pcrd = &pull->coord[c];
788 if (pcrd->params.eType != epullCONSTRAINT)
793 update_pull_coord_reference_value(pcrd, t);
795 pgrp0 = &pull->group[pcrd->params.group[0]];
796 pgrp1 = &pull->group[pcrd->params.group[1]];
798 /* Get the current difference vector */
799 low_get_pull_coord_dr(pull, pcrd, pbc,
800 rnew[pcrd->params.group[1]],
801 rnew[pcrd->params.group[0]],
806 fprintf(debug, "Pull coord %d, iteration %d\n", c, niter);
809 rm = 1.0/(pgrp0->invtm + pgrp1->invtm);
811 switch (pcrd->params.eGeom)
814 if (pcrd->value_ref <= 0)
816 gmx_fatal(FARGS, "The pull constraint reference distance for group %d is <= 0 (%f)", c, pcrd->value_ref);
820 double q, c_a, c_b, c_c;
822 c_a = diprod(r_ij[c], r_ij[c]);
823 c_b = diprod(unc_ij, r_ij[c])*2;
824 c_c = diprod(unc_ij, unc_ij) - dsqr(pcrd->value_ref);
828 q = -0.5*(c_b - sqrt(c_b*c_b - 4*c_a*c_c));
833 q = -0.5*(c_b + sqrt(c_b*c_b - 4*c_a*c_c));
840 "Pull ax^2+bx+c=0: a=%e b=%e c=%e lambda=%e\n",
841 c_a, c_b, c_c, lambda);
845 /* The position corrections dr due to the constraints */
846 dsvmul(-lambda*rm*pgrp1->invtm, r_ij[c], dr1);
847 dsvmul( lambda*rm*pgrp0->invtm, r_ij[c], dr0);
848 dr_tot[c] += -lambda*dnorm(r_ij[c]);
853 /* A 1-dimensional constraint along a vector */
855 for (m = 0; m < DIM; m++)
857 vec[m] = pcrd->vec[m];
858 a += unc_ij[m]*vec[m];
860 /* Select only the component along the vector */
861 dsvmul(a, vec, unc_ij);
862 lambda = a - pcrd->value_ref;
865 fprintf(debug, "Pull inpr %e lambda: %e\n", a, lambda);
868 /* The position corrections dr due to the constraints */
869 dsvmul(-lambda*rm*pgrp1->invtm, vec, dr1);
870 dsvmul( lambda*rm*pgrp0->invtm, vec, dr0);
871 dr_tot[c] += -lambda;
874 gmx_incons("Invalid enumeration value for eGeom");
875 /* Keep static analyzer happy */
885 g0 = pcrd->params.group[0];
886 g1 = pcrd->params.group[1];
887 low_get_pull_coord_dr(pull, pcrd, pbc, rnew[g1], rnew[g0], -1, tmp);
888 low_get_pull_coord_dr(pull, pcrd, pbc, dr1, dr0, -1, tmp3);
890 "Pull cur %8.5f %8.5f %8.5f j:%8.5f %8.5f %8.5f d: %8.5f\n",
891 rnew[g0][0], rnew[g0][1], rnew[g0][2],
892 rnew[g1][0], rnew[g1][1], rnew[g1][2], dnorm(tmp));
894 "Pull ref %8s %8s %8s %8s %8s %8s d: %8.5f\n",
895 "", "", "", "", "", "", pcrd->value_ref);
897 "Pull cor %8.5f %8.5f %8.5f j:%8.5f %8.5f %8.5f d: %8.5f\n",
898 dr0[0], dr0[1], dr0[2],
899 dr1[0], dr1[1], dr1[2],
903 /* Update the COMs with dr */
904 dvec_inc(rnew[pcrd->params.group[1]], dr1);
905 dvec_inc(rnew[pcrd->params.group[0]], dr0);
908 /* Check if all constraints are fullfilled now */
909 for (c = 0; c < pull->ncoord; c++)
911 pull_coord_work_t *pcrd;
913 pcrd = &pull->coord[c];
915 if (pcrd->params.eType != epullCONSTRAINT)
920 low_get_pull_coord_dr(pull, pcrd, pbc,
921 rnew[pcrd->params.group[1]],
922 rnew[pcrd->params.group[0]],
925 switch (pcrd->params.eGeom)
929 fabs(dnorm(unc_ij) - pcrd->value_ref) < pull->params.constr_tol;
934 for (m = 0; m < DIM; m++)
936 vec[m] = pcrd->vec[m];
938 inpr = diprod(unc_ij, vec);
939 dsvmul(inpr, vec, unc_ij);
941 fabs(diprod(unc_ij, vec) - pcrd->value_ref) < pull->params.constr_tol;
949 fprintf(debug, "NOT CONVERGED YET: Group %d:"
950 "d_ref = %f, current d = %f\n",
951 g, pcrd->value_ref, dnorm(unc_ij));
954 bConverged_all = FALSE;
959 /* if after all constraints are dealt with and bConverged is still TRUE
960 we're finished, if not we do another iteration */
962 if (niter > max_iter)
964 gmx_fatal(FARGS, "Too many iterations for constraint run: %d", niter);
967 /* DONE ITERATING, NOW UPDATE COORDINATES AND CALC. CONSTRAINT FORCES */
974 /* update atoms in the groups */
975 for (g = 0; g < pull->ngroup; g++)
977 const pull_group_work_t *pgrp;
980 pgrp = &pull->group[g];
982 /* get the final constraint displacement dr for group g */
983 dvec_sub(rnew[g], pgrp->xp, dr);
987 /* No displacement, no update necessary */
991 /* update the atom positions */
993 for (j = 0; j < pgrp->nat_loc; j++)
995 ii = pgrp->ind_loc[j];
996 if (pgrp->weight_loc)
998 dsvmul(pgrp->wscale*pgrp->weight_loc[j], dr, tmp);
1000 for (m = 0; m < DIM; m++)
1006 for (m = 0; m < DIM; m++)
1008 v[ii][m] += invdt*tmp[m];
1014 /* calculate the constraint forces, used for output and virial only */
1015 for (c = 0; c < pull->ncoord; c++)
1017 pull_coord_work_t *pcrd;
1019 pcrd = &pull->coord[c];
1021 if (pcrd->params.eType != epullCONSTRAINT)
1026 pcrd->f_scal = dr_tot[c]/((pull->group[pcrd->params.group[0]].invtm + pull->group[pcrd->params.group[1]].invtm)*dt*dt);
1028 if (vir != NULL && pcrd->params.eGeom != epullgDIRPBC && bMaster)
1032 /* Add the pull contribution to the virial */
1033 /* We have already checked above that r_ij[c] != 0 */
1034 f_invr = pcrd->f_scal/dnorm(r_ij[c]);
1036 for (j = 0; j < DIM; j++)
1038 for (m = 0; m < DIM; m++)
1040 vir[j][m] -= 0.5*f_invr*r_ij[c][j]*r_ij[c][m];
1046 /* finished! I hope. Give back some memory */
1052 /* Pulling with a harmonic umbrella potential or constant force */
1053 static void do_pull_pot(struct pull_t *pull, t_pbc *pbc, double t, real lambda,
1054 real *V, tensor vir, real *dVdl)
1057 double dev, ndr, invdr = 0;
1060 /* loop over the pull coordinates */
1063 for (c = 0; c < pull->ncoord; c++)
1065 pull_coord_work_t *pcrd;
1067 pcrd = &pull->coord[c];
1069 if (pcrd->params.eType == epullCONSTRAINT)
1074 dev = get_pull_coord_deviation(pull, c, pbc, t);
1076 k = (1.0 - lambda)*pcrd->params.k + lambda*pcrd->params.kB;
1077 dkdl = pcrd->params.kB - pcrd->params.k;
1079 if (pcrd->params.eGeom == epullgDIST)
1081 ndr = dnorm(pcrd->dr);
1088 /* With an harmonic umbrella, the force is 0 at r=0,
1089 * so we can set invdr to any value.
1090 * With a constant force, the force at r=0 is not defined,
1091 * so we zero it (this is anyhow a very rare event).
1099 for (m = 0; m < DIM; m++)
1101 ndr += pcrd->vec[m]*pcrd->dr[m];
1105 switch (pcrd->params.eType)
1108 case epullFLATBOTTOM:
1109 /* The only difference between an umbrella and a flat-bottom
1110 * potential is that a flat-bottom is zero below zero.
1112 if (pcrd->params.eType == epullFLATBOTTOM && dev < 0)
1117 pcrd->f_scal = -k*dev;
1118 *V += 0.5* k*dsqr(dev);
1119 *dVdl += 0.5*dkdl*dsqr(dev);
1127 gmx_incons("Unsupported pull type in do_pull_pot");
1130 if (pcrd->params.eGeom == epullgDIST)
1132 for (m = 0; m < DIM; m++)
1134 pcrd->f[m] = pcrd->f_scal*pcrd->dr[m]*invdr;
1139 for (m = 0; m < DIM; m++)
1141 pcrd->f[m] = pcrd->f_scal*pcrd->vec[m];
1145 if (vir != NULL && pcrd->params.eGeom != epullgDIRPBC)
1147 /* Add the pull contribution to the virial */
1148 for (j = 0; j < DIM; j++)
1150 for (m = 0; m < DIM; m++)
1152 vir[j][m] -= 0.5*pcrd->f[j]*pcrd->dr[m];
1159 real pull_potential(struct pull_t *pull, t_mdatoms *md, t_pbc *pbc,
1160 t_commrec *cr, double t, real lambda,
1161 rvec *x, rvec *f, tensor vir, real *dvdlambda)
1165 assert(pull != NULL);
1167 if (pull->comm.bParticipate)
1169 pull_calc_coms(cr, pull, md, pbc, t, x, NULL);
1171 do_pull_pot(pull, pbc, t, lambda,
1172 &V, MASTER(cr) ? vir : NULL, &dVdl);
1174 /* Distribute forces over the pull groups */
1175 apply_forces(pull, md, f);
1183 return (MASTER(cr) ? V : 0.0);
1186 void pull_constraint(struct pull_t *pull, t_mdatoms *md, t_pbc *pbc,
1187 t_commrec *cr, double dt, double t,
1188 rvec *x, rvec *xp, rvec *v, tensor vir)
1190 assert(pull != NULL);
1192 if (pull->comm.bParticipate)
1194 pull_calc_coms(cr, pull, md, pbc, t, x, xp);
1196 do_constraint(pull, pbc, xp, v, MASTER(cr), vir, dt, t);
1200 static void make_local_pull_group(gmx_ga2la_t ga2la,
1201 pull_group_work_t *pg, int start, int end)
1206 for (i = 0; i < pg->params.nat; i++)
1208 ii = pg->params.ind[i];
1211 if (!ga2la_get_home(ga2la, ii, &ii))
1216 if (ii >= start && ii < end)
1218 /* This is a home atom, add it to the local pull group */
1219 if (pg->nat_loc >= pg->nalloc_loc)
1221 pg->nalloc_loc = over_alloc_dd(pg->nat_loc+1);
1222 srenew(pg->ind_loc, pg->nalloc_loc);
1223 if (pg->epgrppbc == epgrppbcCOS || pg->params.weight != NULL)
1225 srenew(pg->weight_loc, pg->nalloc_loc);
1228 pg->ind_loc[pg->nat_loc] = ii;
1229 if (pg->params.weight != NULL)
1231 pg->weight_loc[pg->nat_loc] = pg->params.weight[i];
1238 void dd_make_local_pull_groups(t_commrec *cr, struct pull_t *pull, t_mdatoms *md)
1243 gmx_bool bMustParticipate;
1259 /* We always make the master node participate, such that it can do i/o
1260 * and to simplify MC type extensions people might have.
1262 bMustParticipate = (comm->bParticipateAll || dd == NULL || DDMASTER(dd));
1264 for (g = 0; g < pull->ngroup; g++)
1268 make_local_pull_group(ga2la, &pull->group[g],
1271 /* We should participate if we have pull or pbc atoms */
1272 if (!bMustParticipate &&
1273 (pull->group[g].nat_loc > 0 ||
1274 (pull->group[g].params.pbcatom >= 0 &&
1275 ga2la_get_home(dd->ga2la, pull->group[g].params.pbcatom, &a))))
1277 bMustParticipate = TRUE;
1281 if (!comm->bParticipateAll)
1283 /* Keep currently not required ranks in the communicator
1284 * if they needed to participate up to 20 decompositions ago.
1285 * This avoids frequent rebuilds due to atoms jumping back and forth.
1287 const gmx_int64_t history_count = 20;
1288 gmx_bool bWillParticipate;
1291 /* Increase the decomposition counter for the current call */
1292 comm->setup_count++;
1294 if (bMustParticipate)
1296 comm->must_count = comm->setup_count;
1301 (comm->bParticipate &&
1302 comm->must_count >= comm->setup_count - history_count);
1304 if (debug && dd != NULL)
1306 fprintf(debug, "Our DD rank (%3d) pull #atoms>0 or master: %d, will be part %d\n",
1307 dd->rank, bMustParticipate, bWillParticipate);
1310 if (bWillParticipate)
1312 /* Count the number of ranks that we want to have participating */
1314 /* Count the number of ranks that need to be added */
1315 count[1] = comm->bParticipate ? 0 : 1;
1323 /* The cost of this global operation will be less that the cost
1324 * of the extra MPI_Comm_split calls that we can avoid.
1326 gmx_sumi(2, count, cr);
1328 /* If we are missing ranks or if we have 20% more ranks than needed
1329 * we make a new sub-communicator.
1331 if (count[1] > 0 || 6*count[0] < 5*comm->nparticipate)
1335 fprintf(debug, "Creating new pull subcommunicator of size %d\n",
1340 if (comm->mpi_comm_com != MPI_COMM_NULL)
1342 MPI_Comm_free(&comm->mpi_comm_com);
1345 /* This might be an extremely expensive operation, so we try
1346 * to avoid this splitting as much as possible.
1349 MPI_Comm_split(dd->mpi_comm_all, bWillParticipate ? 0 : 1, dd->rank,
1350 &comm->mpi_comm_com);
1353 comm->bParticipate = bWillParticipate;
1354 comm->nparticipate = count[0];
1358 /* Since the PBC of atoms might have changed, we need to update the PBC */
1359 pull->bSetPBCatoms = TRUE;
1362 static void init_pull_group_index(FILE *fplog, t_commrec *cr,
1363 int g, pull_group_work_t *pg,
1364 gmx_bool bConstraint, ivec pulldim_con,
1365 const gmx_mtop_t *mtop,
1366 const t_inputrec *ir, real lambda)
1368 int i, ii, d, nfrozen, ndim;
1370 double tmass, wmass, wwmass;
1371 const gmx_groups_t *groups;
1372 gmx_mtop_atomlookup_t alook;
1375 if (EI_ENERGY_MINIMIZATION(ir->eI) || ir->eI == eiBD)
1377 /* There are no masses in the integrator.
1378 * But we still want to have the correct mass-weighted COMs.
1379 * So we store the real masses in the weights.
1380 * We do not set nweight, so these weights do not end up in the tpx file.
1382 if (pg->params.nweight == 0)
1384 snew(pg->params.weight, pg->params.nat);
1393 pg->weight_loc = NULL;
1397 pg->nat_loc = pg->params.nat;
1398 pg->ind_loc = pg->params.ind;
1399 if (pg->epgrppbc == epgrppbcCOS)
1401 snew(pg->weight_loc, pg->params.nat);
1405 pg->weight_loc = pg->params.weight;
1409 groups = &mtop->groups;
1411 alook = gmx_mtop_atomlookup_init(mtop);
1417 for (i = 0; i < pg->params.nat; i++)
1419 ii = pg->params.ind[i];
1420 gmx_mtop_atomnr_to_atom(alook, ii, &atom);
1421 if (bConstraint && ir->opts.nFreeze)
1423 for (d = 0; d < DIM; d++)
1425 if (pulldim_con[d] == 1 &&
1426 ir->opts.nFreeze[ggrpnr(groups, egcFREEZE, ii)][d])
1432 if (ir->efep == efepNO)
1438 m = (1 - lambda)*atom->m + lambda*atom->mB;
1440 if (pg->params.nweight > 0)
1442 w = pg->params.weight[i];
1448 if (EI_ENERGY_MINIMIZATION(ir->eI))
1450 /* Move the mass to the weight */
1453 pg->params.weight[i] = w;
1455 else if (ir->eI == eiBD)
1459 mbd = ir->bd_fric*ir->delta_t;
1463 if (groups->grpnr[egcTC] == NULL)
1465 mbd = ir->delta_t/ir->opts.tau_t[0];
1469 mbd = ir->delta_t/ir->opts.tau_t[groups->grpnr[egcTC][ii]];
1474 pg->params.weight[i] = w;
1481 gmx_mtop_atomlookup_destroy(alook);
1485 /* We can have single atom groups with zero mass with potential pulling
1486 * without cosine weighting.
1488 if (pg->params.nat == 1 && !bConstraint && pg->epgrppbc != epgrppbcCOS)
1490 /* With one atom the mass doesn't matter */
1495 gmx_fatal(FARGS, "The total%s mass of pull group %d is zero",
1496 pg->params.weight ? " weighted" : "", g);
1502 "Pull group %d: %5d atoms, mass %9.3f",
1503 g, pg->params.nat, tmass);
1504 if (pg->params.weight ||
1505 EI_ENERGY_MINIMIZATION(ir->eI) || ir->eI == eiBD)
1507 fprintf(fplog, ", weighted mass %9.3f", wmass*wmass/wwmass);
1509 if (pg->epgrppbc == epgrppbcCOS)
1511 fprintf(fplog, ", cosine weighting will be used");
1513 fprintf(fplog, "\n");
1518 /* A value != 0 signals not frozen, it is updated later */
1524 for (d = 0; d < DIM; d++)
1526 ndim += pulldim_con[d]*pg->params.nat;
1528 if (fplog && nfrozen > 0 && nfrozen < ndim)
1531 "\nWARNING: In pull group %d some, but not all of the degrees of freedom\n"
1532 " that are subject to pulling are frozen.\n"
1533 " For constraint pulling the whole group will be frozen.\n\n",
1542 init_pull(FILE *fplog, const pull_params_t *pull_params, const t_inputrec *ir,
1543 int nfile, const t_filenm fnm[],
1544 gmx_mtop_t *mtop, t_commrec *cr, const output_env_t oenv, real lambda,
1545 gmx_bool bOutFile, unsigned long Flags)
1547 struct pull_t *pull;
1553 /* Copy the pull parameters */
1554 pull->params = *pull_params;
1555 /* Avoid pointer copies */
1556 pull->params.group = NULL;
1557 pull->params.coord = NULL;
1559 pull->ncoord = pull_params->ncoord;
1560 pull->ngroup = pull_params->ngroup;
1561 snew(pull->coord, pull->ncoord);
1562 snew(pull->group, pull->ngroup);
1564 pull->bPotential = FALSE;
1565 pull->bConstraint = FALSE;
1566 pull->bCylinder = FALSE;
1568 for (g = 0; g < pull->ngroup; g++)
1570 pull_group_work_t *pgrp;
1573 pgrp = &pull->group[g];
1575 /* Copy the pull group parameters */
1576 pgrp->params = pull_params->group[g];
1578 /* Avoid pointer copies by allocating and copying arrays */
1579 snew(pgrp->params.ind, pgrp->params.nat);
1580 for (i = 0; i < pgrp->params.nat; i++)
1582 pgrp->params.ind[i] = pull_params->group[g].ind[i];
1584 if (pgrp->params.nweight > 0)
1586 snew(pgrp->params.ind, pgrp->params.nweight);
1587 for (i = 0; i < pgrp->params.nweight; i++)
1589 pgrp->params.weight[i] = pull_params->group[g].weight[i];
1594 for (c = 0; c < pull->ncoord; c++)
1596 pull_coord_work_t *pcrd;
1597 int calc_com_start, calc_com_end, g;
1599 pcrd = &pull->coord[c];
1601 /* Copy all pull coordinate parameters */
1602 pcrd->params = pull_params->coord[c];
1604 switch (pcrd->params.eGeom)
1607 case epullgDIRRELATIVE:
1608 /* Direction vector is determined at each step */
1613 copy_rvec(pull_params->coord[c].vec, pcrd->vec);
1616 gmx_incons("Pull geometry not handled");
1619 if (pcrd->params.eType == epullCONSTRAINT)
1621 /* Check restrictions of the constraint pull code */
1622 if (pcrd->params.eGeom == epullgCYL ||
1623 pcrd->params.eGeom == epullgDIRRELATIVE)
1625 gmx_fatal(FARGS, "Pulling of type %s can not be combined with geometry %s. Consider using pull type %s.",
1626 epull_names[pcrd->params.eType],
1627 epullg_names[pcrd->params.eGeom],
1628 epull_names[epullUMBRELLA]);
1631 pull->bConstraint = TRUE;
1635 pull->bPotential = TRUE;
1638 if (pcrd->params.eGeom == epullgCYL)
1640 pull->bCylinder = TRUE;
1642 /* We only need to calculate the plain COM of a group
1643 * when it is not only used as a cylinder group.
1645 calc_com_start = (pcrd->params.eGeom == epullgCYL ? 1 : 0);
1646 calc_com_end = (pcrd->params.eGeom == epullgDIRRELATIVE ? 4 : 2);
1648 for (g = calc_com_start; g <= calc_com_end; g++)
1650 pull->group[pcrd->params.group[g]].bCalcCOM = TRUE;
1653 /* With non-zero rate the reference value is set at every step */
1654 if (pcrd->params.rate == 0)
1656 /* Initialize the constant reference value */
1657 pcrd->value_ref = pcrd->params.init;
1661 pull->ePBC = ir->ePBC;
1664 case epbcNONE: pull->npbcdim = 0; break;
1665 case epbcXY: pull->npbcdim = 2; break;
1666 default: pull->npbcdim = 3; break;
1671 gmx_bool bAbs, bCos;
1674 for (c = 0; c < pull->ncoord; c++)
1676 if (pull->group[pull->coord[c].params.group[0]].params.nat == 0 ||
1677 pull->group[pull->coord[c].params.group[1]].params.nat == 0)
1683 fprintf(fplog, "\n");
1684 if (pull->bPotential)
1686 fprintf(fplog, "Will apply potential COM pulling\n");
1688 if (pull->bConstraint)
1690 fprintf(fplog, "Will apply constraint COM pulling\n");
1692 fprintf(fplog, "with %d pull coordinate%s and %d group%s\n",
1693 pull->ncoord, pull->ncoord == 1 ? "" : "s",
1694 pull->ngroup, pull->ngroup == 1 ? "" : "s");
1697 fprintf(fplog, "with an absolute reference\n");
1700 for (g = 0; g < pull->ngroup; g++)
1702 if (pull->group[g].params.nat > 1 &&
1703 pull->group[g].params.pbcatom < 0)
1705 /* We are using cosine weighting */
1706 fprintf(fplog, "Cosine weighting is used for group %d\n", g);
1712 please_cite(fplog, "Engin2010");
1716 pull->bRefAt = FALSE;
1718 for (g = 0; g < pull->ngroup; g++)
1720 pull_group_work_t *pgrp;
1722 pgrp = &pull->group[g];
1723 pgrp->epgrppbc = epgrppbcNONE;
1724 if (pgrp->params.nat > 0)
1726 /* There is an issue when a group is used in multiple coordinates
1727 * and constraints are applied in different dimensions with atoms
1728 * frozen in some, but not all dimensions.
1729 * Since there is only one mass array per group, we can't have
1730 * frozen/non-frozen atoms for different coords at the same time.
1731 * But since this is a very exotic case, we don't check for this.
1732 * A warning is printed in init_pull_group_index.
1735 gmx_bool bConstraint;
1736 ivec pulldim, pulldim_con;
1738 /* Loop over all pull coordinates to see along which dimensions
1739 * this group is pulled and if it is involved in constraints.
1741 bConstraint = FALSE;
1742 clear_ivec(pulldim);
1743 clear_ivec(pulldim_con);
1744 for (c = 0; c < pull->ncoord; c++)
1746 if (pull->coord[c].params.group[0] == g ||
1747 pull->coord[c].params.group[1] == g ||
1748 (pull->coord[c].params.eGeom == epullgDIRRELATIVE &&
1749 (pull->coord[c].params.group[2] == g ||
1750 pull->coord[c].params.group[3] == g)))
1752 for (m = 0; m < DIM; m++)
1754 if (pull->coord[c].params.dim[m] == 1)
1758 if (pull->coord[c].params.eType == epullCONSTRAINT)
1768 /* Determine if we need to take PBC into account for calculating
1769 * the COM's of the pull groups.
1771 GMX_RELEASE_ASSERT(pull->npbcdim <= DIM, "npbcdim must be <= the number of dimensions");
1772 for (m = 0; m < pull->npbcdim; m++)
1774 GMX_RELEASE_ASSERT(m <= DIM, "npbcdim must be <= the number of dimensions");
1775 if (pulldim[m] == 1 && pgrp->params.nat > 1)
1777 if (pgrp->params.pbcatom >= 0)
1779 pgrp->epgrppbc = epgrppbcREFAT;
1780 pull->bRefAt = TRUE;
1784 if (pgrp->params.weight != NULL)
1786 gmx_fatal(FARGS, "Pull groups can not have relative weights and cosine weighting at same time");
1788 pgrp->epgrppbc = epgrppbcCOS;
1789 if (pull->cosdim >= 0 && pull->cosdim != m)
1791 gmx_fatal(FARGS, "Can only use cosine weighting with pulling in one dimension (use mdp option pull-coord?-dim)");
1797 /* Set the indices */
1798 init_pull_group_index(fplog, cr, g, pgrp,
1799 bConstraint, pulldim_con,
1804 /* Absolute reference, set the inverse mass to zero.
1805 * This is only relevant (and used) with constraint pulling.
1812 /* If we use cylinder coordinates, do some initialising for them */
1813 if (pull->bCylinder)
1815 snew(pull->dyna, pull->ncoord);
1817 for (c = 0; c < pull->ncoord; c++)
1819 const pull_coord_work_t *pcrd;
1821 pcrd = &pull->coord[c];
1823 if (pcrd->params.eGeom == epullgCYL)
1825 if (pull->group[pcrd->params.group[0]].params.nat == 0)
1827 gmx_fatal(FARGS, "A cylinder pull group is not supported when using absolute reference!\n");
1836 /* Use a sub-communicator when we have more than 32 ranks */
1837 comm->bParticipateAll = (cr == NULL || !DOMAINDECOMP(cr) ||
1838 cr->dd->nnodes <= 32 ||
1839 getenv("GMX_PULL_PARTICIPATE_ALL") != NULL);
1840 /* This sub-commicator is not used with comm->bParticipateAll,
1841 * so we can always initialize it to NULL.
1843 comm->mpi_comm_com = MPI_COMM_NULL;
1844 comm->nparticipate = 0;
1846 /* No MPI: 1 rank: all ranks pull */
1847 comm->bParticipateAll = TRUE;
1849 comm->bParticipate = comm->bParticipateAll;
1850 comm->setup_count = 0;
1851 comm->must_count = 0;
1853 if (!comm->bParticipateAll && fplog != NULL)
1855 fprintf(fplog, "Will use a sub-communicator for pull communication\n");
1860 comm->dbuf_cyl = NULL;
1862 /* We still need to initialize the PBC reference coordinates */
1863 pull->bSetPBCatoms = TRUE;
1865 /* Only do I/O when we are doing dynamics and if we are the MASTER */
1870 if (pull->params.nstxout > 0)
1872 pull->out_x = open_pull_out(opt2fn("-px", nfile, fnm), pull, oenv,
1875 if (pull->params.nstfout > 0)
1877 pull->out_f = open_pull_out(opt2fn("-pf", nfile, fnm), pull, oenv,
1885 static void destroy_pull_group(pull_group_work_t *pgrp)
1887 if (pgrp->ind_loc != pgrp->params.ind)
1889 sfree(pgrp->ind_loc);
1891 if (pgrp->weight_loc != pgrp->params.weight)
1893 sfree(pgrp->weight_loc);
1898 sfree(pgrp->params.ind);
1899 sfree(pgrp->params.weight);
1902 static void destroy_pull(struct pull_t *pull)
1906 for (i = 0; i < pull->ngroup; i++)
1908 destroy_pull_group(&pull->group[i]);
1910 for (i = 0; i < pull->ncoord; i++)
1912 if (pull->coord[i].params.eGeom == epullgCYL)
1914 destroy_pull_group(&(pull->dyna[i]));
1922 if (pull->comm.mpi_comm_com != MPI_COMM_NULL)
1924 MPI_Comm_free(&pull->comm.mpi_comm_com);
1927 sfree(pull->comm.rbuf);
1928 sfree(pull->comm.dbuf);
1929 sfree(pull->comm.dbuf_cyl);
1934 void finish_pull(struct pull_t *pull)
1938 gmx_fio_fclose(pull->out_x);
1942 gmx_fio_fclose(pull->out_f);
1948 gmx_bool pull_have_potential(const struct pull_t *pull)
1950 return pull->bPotential;
1953 gmx_bool pull_have_constraint(const struct pull_t *pull)
1955 return pull->bConstraint;