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,2016,2017 by the GROMACS development team.
7 * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
8 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
9 * and including many others, as listed in the AUTHORS file in the
10 * top-level source directory and at http://www.gromacs.org.
12 * GROMACS is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2.1
15 * of the License, or (at your option) any later version.
17 * GROMACS is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with GROMACS; if not, see
24 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
25 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 * If you want to redistribute modifications to GROMACS, please
28 * consider that scientific software is very special. Version
29 * control is crucial - bugs must be traceable. We will be happy to
30 * consider code for inclusion in the official distribution, but
31 * derived work must not be called official GROMACS. Details are found
32 * in the README & COPYING files - if they are missing, get the
33 * official version at http://www.gromacs.org.
35 * To help us fund GROMACS development, we humbly ask that you cite
36 * the research papers on the package. Check out http://www.gromacs.org.
49 #include "gromacs/commandline/filenm.h"
50 #include "gromacs/domdec/domdec_struct.h"
51 #include "gromacs/fileio/gmxfio.h"
52 #include "gromacs/fileio/xvgr.h"
53 #include "gromacs/gmxlib/network.h"
54 #include "gromacs/gmxlib/nrnb.h"
55 #include "gromacs/linearalgebra/nrjac.h"
56 #include "gromacs/math/functions.h"
57 #include "gromacs/math/units.h"
58 #include "gromacs/math/utilities.h"
59 #include "gromacs/math/vec.h"
60 #include "gromacs/math/vectypes.h"
61 #include "gromacs/mdlib/broadcaststructs.h"
62 #include "gromacs/mdlib/constr.h"
63 #include "gromacs/mdlib/groupcoord.h"
64 #include "gromacs/mdlib/stat.h"
65 #include "gromacs/mdlib/update.h"
66 #include "gromacs/mdrunutility/handlerestart.h"
67 #include "gromacs/mdtypes/commrec.h"
68 #include "gromacs/mdtypes/edsamhistory.h"
69 #include "gromacs/mdtypes/inputrec.h"
70 #include "gromacs/mdtypes/md_enums.h"
71 #include "gromacs/mdtypes/observableshistory.h"
72 #include "gromacs/mdtypes/state.h"
73 #include "gromacs/pbcutil/pbc.h"
74 #include "gromacs/topology/mtop_lookup.h"
75 #include "gromacs/topology/topology.h"
76 #include "gromacs/utility/cstringutil.h"
77 #include "gromacs/utility/fatalerror.h"
78 #include "gromacs/utility/gmxassert.h"
79 #include "gromacs/utility/logger.h"
80 #include "gromacs/utility/smalloc.h"
81 #include "gromacs/utility/strconvert.h"
85 /*! \brief Identifies the type of ED: none, normal ED, flooding. */
86 enum class EssentialDynamicsType
88 //! No essential dynamics
90 //! Essential dynamics sampling
92 //! Essential dynamics flooding
96 /*! \brief Identify on which structure to operate. */
97 enum class EssentialDynamicsStructure
99 //! Reference structure
101 //! Average Structure
109 /*! \brief Essential dynamics vector.
110 * TODO: split into working data and input data
111 * NOTE: called eigvec, because traditionally eigenvectors from PCA analysis
112 * were used as essential dynamics vectors, however, vectors used for ED need
113 * not have any special properties
117 //! nr of eigenvectors
119 //! index nrs of eigenvectors
121 //! stepsizes (per eigenvector)
122 real* stpsz = nullptr;
123 //! eigenvector components
124 rvec** vec = nullptr;
125 //! instantaneous x projections
126 real* xproj = nullptr;
127 //! instantaneous f projections
128 real* fproj = nullptr;
129 //! instantaneous radius
131 //! starting or target projections
132 real* refproj = nullptr;
135 /*! \brief Essential dynamics vectors per method implementation.
139 //! only monitored, no constraints
141 //! fixed linear constraints
142 t_eigvec linfix = {};
143 //! acceptance linear constraints
144 t_eigvec linacc = {};
145 //! fixed radial constraints (exp)
146 t_eigvec radfix = {};
147 //! acceptance radial constraints (exp)
148 t_eigvec radacc = {};
149 //! acceptance rad. contraction constr.
150 t_eigvec radcon = {};
153 /*! \brief Essential dynamics flooding parameters and work data.
154 * TODO: split into working data and input parameters
155 * NOTE: The implementation here follows:
156 * O.E. Lange, L.V. Schafer, and H. Grubmuller,
157 * “Flooding in GROMACS: Accelerated barrier crossings in molecular dynamics,”
158 * J. Comp. Chem., 27 1693–1702 (2006)
162 /*! \brief Target destabilisation free energy.
163 * Controls the flooding potential strength.
164 * Linked to the expected speed-up of mean first passage time out of flooded minimum */
166 //! Do not calculate a flooding potential, instead flood with a constant force
167 bool bConstForce = false;
168 //! Relaxation time scale for slowest flooded degree of freedom
170 //! Current estimated destabilisation free energy
172 //! Flooding energy, acting as a proportionality factor for the flooding potential
174 //! Boltzmann constant times temperature, provided by user
176 //! The flooding potential
178 //! Integration time step
180 //! Inital flooding strenth
182 //! Empirical global scaling parameter of the essential dynamics vectors.
184 //! The forces from flooding in atom coordinate space (in contrast to projections onto essential dynamics vectors)
185 rvec* forces_cartesian = nullptr;
186 //! The vectors along which to flood
188 //! Use flooding for harmonic restraint on the eigenvector
189 bool bHarmonic = false;
190 //! The initial reference projection of the flooding vectors. Only with harmonic restraint.
191 real* initialReferenceProjection = nullptr;
192 //! The current reference projection is the initialReferenceProjection + step * slope. Only with harmonic restraint.
193 real* referenceProjectionSlope = nullptr;
198 /* This type is for the average, reference, target, and origin structure */
201 int nr = 0; /* number of atoms this structure contains */
202 int nr_loc = 0; /* number of atoms on local node */
203 int* anrs = nullptr; /* atom index numbers */
204 int* anrs_loc = nullptr; /* local atom index numbers */
205 int nalloc_loc = 0; /* allocation size of anrs_loc */
206 int* c_ind = nullptr; /* at which position of the whole anrs
207 * array is a local atom?, i.e.
208 * c_ind[0...nr_loc-1] gives the atom index
209 * with respect to the collective
210 * anrs[0...nr-1] array */
211 rvec* x = nullptr; /* positions for this structure */
212 rvec* x_old = nullptr; /* Last positions which have the correct PBC
213 representation of the ED group. In
214 combination with keeping track of the
215 shift vectors, the ED group can always
217 real* m = nullptr; /* masses */
218 real mtot = 0.; /* total mass (only used in sref) */
219 real* sqrtm = nullptr; /* sqrt of the masses used for mass-
220 * weighting of analysis (only used in sav) */
226 int nini = 0; /* total Nr of atoms */
227 gmx_bool fitmas = false; /* true if trans fit with cm */
228 gmx_bool pcamas = false; /* true if mass-weighted PCA */
229 int presteps = 0; /* number of steps to run without any
230 * perturbations ... just monitoring */
231 int outfrq = 0; /* freq (in steps) of writing to edo */
232 int maxedsteps = 0; /* max nr of steps per cycle */
234 /* all gmx_edx datasets are copied to all nodes in the parallel case */
235 gmx_edx sref = {}; /* reference positions, to these fitting
237 gmx_bool bRefEqAv = false; /* If true, reference & average indices
238 * are the same. Used for optimization */
239 gmx_edx sav = {}; /* average positions */
240 gmx_edx star = {}; /* target positions */
241 gmx_edx sori = {}; /* origin positions */
243 t_edvecs vecs = {}; /* eigenvectors */
244 real slope = 0; /* minimal slope in acceptance radexp */
246 t_edflood flood = {}; /* parameters especially for flooding */
247 struct t_ed_buffer* buf = nullptr; /* handle to local buffers */
255 EssentialDynamicsType eEDtype = EssentialDynamicsType::None;
256 //! output file pointer
258 std::vector<t_edpar> edpar;
259 gmx_bool bFirst = false;
261 gmx_edsam::~gmx_edsam()
265 /* edo is opened sometimes with xvgropen, sometimes with
266 * gmx_fio_fopen, so we use the least common denominator for
276 rvec old_transvec, older_transvec, transvec_compact;
277 rvec* xcoll; /* Positions from all nodes, this is the
278 collective set we work on.
279 These are the positions of atoms with
280 average structure indices */
281 rvec* xc_ref; /* same but with reference structure indices */
282 ivec* shifts_xcoll; /* Shifts for xcoll */
283 ivec* extra_shifts_xcoll; /* xcoll shift changes since last NS step */
284 ivec* shifts_xc_ref; /* Shifts for xc_ref */
285 ivec* extra_shifts_xc_ref; /* xc_ref shift changes since last NS step */
286 gmx_bool bUpdateShifts; /* TRUE in NS steps to indicate that the
287 ED shifts for this ED group need to
292 /* definition of ED buffer structure */
295 struct t_fit_to_ref* fit_to_ref;
296 struct t_do_edfit* do_edfit;
297 struct t_do_edsam* do_edsam;
298 struct t_do_radcon* do_radcon;
303 class EssentialDynamics::Impl
306 // TODO: move all fields from gmx_edsam here and remove gmx_edsam
307 gmx_edsam essentialDynamics_;
309 EssentialDynamics::EssentialDynamics() : impl_(new Impl) {}
310 EssentialDynamics::~EssentialDynamics() = default;
312 gmx_edsam* EssentialDynamics::getLegacyED()
314 return &impl_->essentialDynamics_;
318 /* Function declarations */
319 static void fit_to_reference(rvec* xcoll, rvec transvec, matrix rotmat, t_edpar* edi);
320 static void translate_and_rotate(rvec* x, int nat, rvec transvec, matrix rotmat);
321 static real rmsd_from_structure(rvec* x, struct gmx_edx* s);
324 /*! \brief Read in the essential dynamics input file and return its contents.
325 * \param[in] fn the file name of the edi file to be read
326 * \param[in] nr_mdatoms the number of atoms in the simulation
327 * \returns A vector of containing the essentiail dyanmics parameters.
328 * NOTE: edi files may that it may contain several ED data sets from concatenated edi files.
329 * The standard case would be a single ED data set, though. */
330 std::vector<t_edpar> read_edi_file(const char* fn, int nr_mdatoms);
332 static void crosscheck_edi_file_vs_checkpoint(const gmx_edsam& ed, edsamhistory_t* EDstate);
333 static void init_edsamstate(const gmx_edsam& ed, edsamhistory_t* EDstate);
334 static void write_edo_legend(gmx_edsam* ed, int nED, const gmx_output_env_t* oenv);
335 /* End function declarations */
337 /* Define formats for the column width in the output file */
338 const char EDcol_sfmt[] = "%17s";
339 const char EDcol_efmt[] = "%17.5e";
340 const char EDcol_ffmt[] = "%17f";
342 /* Define a formats for reading, otherwise cppcheck complains for scanf without width limits */
343 const char max_ev_fmt_d[] = "%7d"; /* Number of eigenvectors. 9,999,999 should be enough */
344 const char max_ev_fmt_lf[] = "%12lf";
345 const char max_ev_fmt_dlf[] = "%7d%12lf";
346 const char max_ev_fmt_dlflflf[] = "%7d%12lf%12lf%12lf";
347 const char max_ev_fmt_lelele[] = "%12le%12le%12le";
351 /*!\brief Determines whether to perform essential dynamics constraints other than flooding.
352 * \param[in] edi the essential dynamics parameters
353 * \returns true if essential dyanmics constraints need to be performed
355 bool bNeedDoEdsam(const t_edpar& edi)
357 return (edi.vecs.mon.neig != 0) || (edi.vecs.linfix.neig != 0) || (edi.vecs.linacc.neig != 0)
358 || (edi.vecs.radfix.neig != 0) || (edi.vecs.radacc.neig != 0) || (edi.vecs.radcon.neig != 0);
363 /* Multiple ED groups will be labeled with letters instead of numbers
364 * to avoid confusion with eigenvector indices */
365 static char get_EDgroupChar(int nr_edi, int nED)
373 * nr_edi = 2 -> B ...
375 return 'A' + nr_edi - 1;
380 /*! \brief The mass-weighted inner product of two coordinate vectors.
381 * Does not subtract average positions, projection on single eigenvector is returned
382 * used by: do_linfix, do_linacc, do_radfix, do_radacc, do_radcon
383 * Average position is subtracted in ed_apply_constraints prior to calling projectx
384 * \param[in] edi Essential dynamics parameters
385 * \param[in] xcoll vector of atom coordinates
386 * \param[in] vec vector of coordinates to project onto
387 * \return mass-weighted projection.
389 real projectx(const t_edpar& edi, rvec* xcoll, rvec* vec)
395 for (i = 0; i < edi.sav.nr; i++)
397 proj += edi.sav.sqrtm[i] * iprod(vec[i], xcoll[i]);
402 /*!\brief Project coordinates onto vector after substracting average position.
403 * projection is stored in vec->refproj which is used for radacc, radfix,
404 * radcon and center of flooding potential.
405 * Average positions are first substracted from x, then added back again.
406 * \param[in] edi essential dynamics parameters with average position
407 * \param[in] x Coordinates to be projected
408 * \param[out] vec eigenvector, radius and refproj are overwritten here
410 void rad_project(const t_edpar& edi, rvec* x, t_eigvec* vec)
415 /* Subtract average positions */
416 for (i = 0; i < edi.sav.nr; i++)
418 rvec_dec(x[i], edi.sav.x[i]);
421 for (i = 0; i < vec->neig; i++)
423 vec->refproj[i] = projectx(edi, x, vec->vec[i]);
424 rad += gmx::square((vec->refproj[i] - vec->xproj[i]));
426 vec->radius = sqrt(rad);
428 /* Add average positions */
429 for (i = 0; i < edi.sav.nr; i++)
431 rvec_inc(x[i], edi.sav.x[i]);
435 /*!\brief Projects coordinates onto eigenvectors and stores result in vec->xproj.
436 * Mass-weighting is applied. Subtracts average positions prior to projection and add
437 * them afterwards to retain the unchanged vector.
438 * \param[in] x The coordinates to project to an eigenvector
439 * \param[in,out] vec The eigenvectors
440 * \param[in] edi essential dynamics parameters holding average structure and masses
442 void project_to_eigvectors(rvec* x, t_eigvec* vec, const t_edpar& edi)
449 /* Subtract average positions */
450 for (int i = 0; i < edi.sav.nr; i++)
452 rvec_dec(x[i], edi.sav.x[i]);
455 for (int i = 0; i < vec->neig; i++)
457 vec->xproj[i] = projectx(edi, x, vec->vec[i]);
460 /* Add average positions */
461 for (int i = 0; i < edi.sav.nr; i++)
463 rvec_inc(x[i], edi.sav.x[i]);
468 /* Project vector x onto all edi->vecs (mon, linfix,...) */
469 static void project(rvec* x, /* positions to project */
470 t_edpar* edi) /* edi data set */
472 /* It is not more work to subtract the average position in every
473 * subroutine again, because these routines are rarely used simultaneously */
474 project_to_eigvectors(x, &edi->vecs.mon, *edi);
475 project_to_eigvectors(x, &edi->vecs.linfix, *edi);
476 project_to_eigvectors(x, &edi->vecs.linacc, *edi);
477 project_to_eigvectors(x, &edi->vecs.radfix, *edi);
478 project_to_eigvectors(x, &edi->vecs.radacc, *edi);
479 project_to_eigvectors(x, &edi->vecs.radcon, *edi);
484 /*!\brief Evaluates the distance from reference to current eigenvector projection.
485 * \param[in] vec eigenvector
488 real calc_radius(const t_eigvec& vec)
492 for (int i = 0; i < vec.neig; i++)
494 rad += gmx::square((vec.refproj[i] - vec.xproj[i]));
507 static void do_edfit(int natoms, rvec* xp, rvec* x, matrix R, t_edpar* edi)
509 /* this is a copy of do_fit with some modifications */
510 int c, r, n, j, i, irot;
511 double d[6], xnr, xpc;
516 struct t_do_edfit* loc;
519 if (edi->buf->do_edfit != nullptr)
526 snew(edi->buf->do_edfit, 1);
528 loc = edi->buf->do_edfit;
532 snew(loc->omega, 2 * DIM);
533 snew(loc->om, 2 * DIM);
534 for (i = 0; i < 2 * DIM; i++)
536 snew(loc->omega[i], 2 * DIM);
537 snew(loc->om[i], 2 * DIM);
541 for (i = 0; (i < 6); i++)
544 for (j = 0; (j < 6); j++)
546 loc->omega[i][j] = 0;
551 /* calculate the matrix U */
553 for (n = 0; (n < natoms); n++)
555 for (c = 0; (c < DIM); c++)
558 for (r = 0; (r < DIM); r++)
561 u[c][r] += xnr * xpc;
566 /* construct loc->omega */
567 /* loc->omega is symmetric -> loc->omega==loc->omega' */
568 for (r = 0; (r < 6); r++)
570 for (c = 0; (c <= r); c++)
572 if ((r >= 3) && (c < 3))
574 loc->omega[r][c] = u[r - 3][c];
575 loc->omega[c][r] = u[r - 3][c];
579 loc->omega[r][c] = 0;
580 loc->omega[c][r] = 0;
585 /* determine h and k */
586 jacobi(loc->omega, 6, d, loc->om, &irot);
590 fprintf(stderr, "IROT=0\n");
593 index = 0; /* For the compiler only */
595 for (j = 0; (j < 3); j++)
598 for (i = 0; (i < 6); i++)
607 for (i = 0; (i < 3); i++)
609 vh[j][i] = M_SQRT2 * loc->om[i][index];
610 vk[j][i] = M_SQRT2 * loc->om[i + DIM][index];
615 for (c = 0; (c < 3); c++)
617 for (r = 0; (r < 3); r++)
619 R[c][r] = vk[0][r] * vh[0][c] + vk[1][r] * vh[1][c] + vk[2][r] * vh[2][c];
624 for (c = 0; (c < 3); c++)
626 for (r = 0; (r < 3); r++)
628 R[c][r] = vk[0][r] * vh[0][c] + vk[1][r] * vh[1][c] - vk[2][r] * vh[2][c];
635 static void rmfit(int nat, rvec* xcoll, const rvec transvec, matrix rotmat)
642 * The inverse rotation is described by the transposed rotation matrix */
643 transpose(rotmat, tmat);
644 rotate_x(xcoll, nat, tmat);
646 /* Remove translation */
647 vec[XX] = -transvec[XX];
648 vec[YY] = -transvec[YY];
649 vec[ZZ] = -transvec[ZZ];
650 translate_x(xcoll, nat, vec);
654 /**********************************************************************************
655 ******************** FLOODING ****************************************************
656 **********************************************************************************
658 The flooding ability was added later to edsam. Many of the edsam functionality could be reused for that purpose.
659 The flooding covariance matrix, i.e. the selected eigenvectors and their corresponding eigenvalues are
660 read as 7th Component Group. The eigenvalues are coded into the stepsize parameter (as used by -linfix or -linacc).
662 do_md clls right in the beginning the function init_edsam, which reads the edi file, saves all the necessary information in
663 the edi structure and calls init_flood, to initialise some extra fields in the edi->flood structure.
665 since the flooding acts on forces do_flood is called from the function force() (force.c), while the other
666 edsam functionality is hooked into md via the update() (update.c) function acting as constraint on positions.
668 do_flood makes a copy of the positions,
669 fits them, projects them computes flooding_energy, and flooding forces. The forces are computed in the
670 space of the eigenvectors and are then blown up to the full cartesian space and rotated back to remove the
671 fit. Then do_flood adds these forces to the forcefield-forces
672 (given as parameter) and updates the adaptive flooding parameters Efl and deltaF.
674 To center the flooding potential at a different location one can use the -ori option in make_edi. The ori
675 structure is projected to the system of eigenvectors and then this position in the subspace is used as
676 center of the flooding potential. If the option is not used, the center will be zero in the subspace,
677 i.e. the average structure as given in the make_edi file.
679 To use the flooding potential as restraint, make_edi has the option -restrain, which leads to inverted
680 signs of alpha2 and Efl, such that the sign in the exponential of Vfl is not inverted but the sign of
681 Vfl is inverted. Vfl = Efl * exp (- .../Efl/alpha2*x^2...) With tau>0 the negative Efl will grow slowly
682 so that the restraint is switched off slowly. When Efl==0 and inverted flooding is ON is reached no
683 further adaption is applied, Efl will stay constant at zero.
685 To use restraints with harmonic potentials switch -restrain and -harmonic. Then the eigenvalues are
686 used as spring constants for the harmonic potential.
687 Note that eq3 in the flooding paper (J. Comp. Chem. 2006, 27, 1693-1702) defines the parameter lambda \
688 as the inverse of the spring constant, whereas the implementation uses lambda as the spring constant.
690 To use more than one flooding matrix just concatenate several .edi files (cat flood1.edi flood2.edi > flood_all.edi)
691 the routine read_edi_file reads all of theses flooding files.
692 The structure t_edi is now organized as a list of t_edis and the function do_flood cycles through the list
693 calling the do_single_flood() routine for every single entry. Since every state variables have been kept in one
694 edi there is no interdependence whatsoever. The forces are added together.
696 To write energies into the .edr file, call the function
697 get_flood_enx_names(char**, int *nnames) to get the Header (Vfl1 Vfl2... Vfln)
699 get_flood_energies(real Vfl[],int nnames);
702 - one could program the whole thing such that Efl, Vfl and deltaF is written to the .edr file. -- i dont know how to do that, yet.
704 Maybe one should give a range of atoms for which to remove motion, so that motion is removed with
705 two edsam files from two peptide chains
708 // TODO split this into multiple files
711 /*!\brief Output flooding simulation settings and results to file.
712 * \param[in] edi Essential dynamics input parameters
713 * \param[in] fp output file
714 * \param[in] rmsd rmsd to reference structure
716 void write_edo_flood(const t_edpar& edi, FILE* fp, real rmsd)
718 /* Output how well we fit to the reference structure */
719 fprintf(fp, EDcol_ffmt, rmsd);
721 for (int i = 0; i < edi.flood.vecs.neig; i++)
723 fprintf(fp, EDcol_efmt, edi.flood.vecs.xproj[i]);
725 /* Check whether the reference projection changes with time (this can happen
726 * in case flooding is used as harmonic restraint). If so, output the
727 * current reference projection */
728 if (edi.flood.bHarmonic && edi.flood.referenceProjectionSlope[i] != 0.0)
730 fprintf(fp, EDcol_efmt, edi.flood.vecs.refproj[i]);
733 /* Output Efl if we are doing adaptive flooding */
734 if (0 != edi.flood.tau)
736 fprintf(fp, EDcol_efmt, edi.flood.Efl);
738 fprintf(fp, EDcol_efmt, edi.flood.Vfl);
740 /* Output deltaF if we are doing adaptive flooding */
741 if (0 != edi.flood.tau)
743 fprintf(fp, EDcol_efmt, edi.flood.deltaF);
745 fprintf(fp, EDcol_efmt, edi.flood.vecs.fproj[i]);
751 /* From flood.xproj compute the Vfl(x) at this point */
752 static real flood_energy(t_edpar* edi, int64_t step)
754 /* compute flooding energy Vfl
755 Vfl = Efl * exp( - \frac {kT} {2Efl alpha^2} * sum_i { \lambda_i c_i^2 } )
756 \lambda_i is the reciprocal eigenvalue 1/\sigma_i
757 it is already computed by make_edi and stored in stpsz[i]
759 Vfl = - Efl * 1/2(sum _i {\frac 1{\lambda_i} c_i^2})
766 /* Each time this routine is called (i.e. each time step), we add a small
767 * value to the reference projection. This way a harmonic restraint towards
768 * a moving reference is realized. If no value for the additive constant
769 * is provided in the edi file, the reference will not change. */
770 if (edi->flood.bHarmonic)
772 for (i = 0; i < edi->flood.vecs.neig; i++)
774 edi->flood.vecs.refproj[i] = edi->flood.initialReferenceProjection[i]
775 + step * edi->flood.referenceProjectionSlope[i];
780 /* Compute sum which will be the exponent of the exponential */
781 for (i = 0; i < edi->flood.vecs.neig; i++)
783 /* stpsz stores the reciprocal eigenvalue 1/sigma_i */
784 sum += edi->flood.vecs.stpsz[i] * (edi->flood.vecs.xproj[i] - edi->flood.vecs.refproj[i])
785 * (edi->flood.vecs.xproj[i] - edi->flood.vecs.refproj[i]);
788 /* Compute the Gauss function*/
789 if (edi->flood.bHarmonic)
791 Vfl = -0.5 * edi->flood.Efl * sum; /* minus sign because Efl is negative, if restrain is on. */
795 Vfl = edi->flood.Efl != 0
797 * std::exp(-edi->flood.kT / 2 / edi->flood.Efl / edi->flood.alpha2 * sum)
805 /* From the position and from Vfl compute forces in subspace -> store in edi->vec.flood.fproj */
806 static void flood_forces(t_edpar* edi)
808 /* compute the forces in the subspace of the flooding eigenvectors
809 * by the formula F_i= V_{fl}(c) * ( \frac {kT} {E_{fl}} \lambda_i c_i */
812 real energy = edi->flood.Vfl;
815 if (edi->flood.bHarmonic)
817 for (i = 0; i < edi->flood.vecs.neig; i++)
819 edi->flood.vecs.fproj[i] = edi->flood.Efl * edi->flood.vecs.stpsz[i]
820 * (edi->flood.vecs.xproj[i] - edi->flood.vecs.refproj[i]);
825 for (i = 0; i < edi->flood.vecs.neig; i++)
827 /* if Efl is zero the forces are zero if not use the formula */
828 edi->flood.vecs.fproj[i] =
830 ? edi->flood.kT / edi->flood.Efl / edi->flood.alpha2 * energy
831 * edi->flood.vecs.stpsz[i]
832 * (edi->flood.vecs.xproj[i] - edi->flood.vecs.refproj[i])
840 /*!\brief Raise forces from subspace into cartesian space.
841 * This function lifts the forces from the subspace to the cartesian space
842 * all the values not contained in the subspace are assumed to be zero and then
843 * a coordinate transformation from eigenvector to cartesian vectors is performed
844 * The nonexistent values don't have to be set to zero explicitly, they would occur
845 * as zero valued summands, hence we just stop to compute this part of the sum.
846 * For every atom we add all the contributions to this atom from all the different eigenvectors.
847 * NOTE: one could add directly to the forcefield forces, would mean we wouldn't have to clear the
848 * field forces_cart prior the computation, but we compute the forces separately
849 * to have them accessible for diagnostics
851 * \param[in] edi Essential dynamics input parameters
852 * \param[out] forces_cart The cartesian forces
855 void flood_blowup(const t_edpar& edi, rvec* forces_cart)
857 const real* forces_sub = edi.flood.vecs.fproj;
858 /* Calculate the cartesian forces for the local atoms */
860 /* Clear forces first */
861 for (int j = 0; j < edi.sav.nr_loc; j++)
863 clear_rvec(forces_cart[j]);
866 /* Now compute atomwise */
867 for (int j = 0; j < edi.sav.nr_loc; j++)
869 /* Compute forces_cart[edi.sav.anrs[j]] */
870 for (int eig = 0; eig < edi.flood.vecs.neig; eig++)
873 /* Force vector is force * eigenvector (compute only atom j) */
874 svmul(forces_sub[eig], edi.flood.vecs.vec[eig][edi.sav.c_ind[j]], addedForce);
875 /* Add this vector to the cartesian forces */
876 rvec_inc(forces_cart[j], addedForce);
884 /* Update the values of Efl, deltaF depending on tau and Vfl */
885 static void update_adaption(t_edpar* edi)
887 /* this function updates the parameter Efl and deltaF according to the rules given in
888 * 'predicting unimolecular chemical reactions: chemical flooding' M Mueller et al,
891 if ((edi->flood.tau < 0 ? -edi->flood.tau : edi->flood.tau) > 0.00000001)
893 edi->flood.Efl = edi->flood.Efl
894 + edi->flood.dt / edi->flood.tau * (edi->flood.deltaF0 - edi->flood.deltaF);
895 /* check if restrain (inverted flooding) -> don't let EFL become positive */
896 if (edi->flood.alpha2 < 0 && edi->flood.Efl > -0.00000001)
901 edi->flood.deltaF = (1 - edi->flood.dt / edi->flood.tau) * edi->flood.deltaF
902 + edi->flood.dt / edi->flood.tau * edi->flood.Vfl;
907 static void do_single_flood(FILE* edo,
908 gmx::ArrayRef<const gmx::RVec> coords,
909 gmx::ArrayRef<gmx::RVec> force,
914 gmx_bool bNS) /* Are we in a neighbor searching step? */
917 matrix rotmat; /* rotation matrix */
918 matrix tmat; /* inverse rotation */
919 rvec transvec; /* translation vector */
921 struct t_do_edsam* buf;
924 buf = edi->buf->do_edsam;
927 /* Broadcast the positions of the AVERAGE structure such that they are known on
928 * every processor. Each node contributes its local positions x and stores them in
929 * the collective ED array buf->xcoll */
930 communicate_group_positions(cr,
933 buf->extra_shifts_xcoll,
935 as_rvec_array(coords.data()),
943 /* Only assembly REFERENCE positions if their indices differ from the average ones */
946 communicate_group_positions(cr,
949 buf->extra_shifts_xc_ref,
951 as_rvec_array(coords.data()),
960 /* If bUpdateShifts was TRUE, the shifts have just been updated in get_positions.
961 * We do not need to update the shifts until the next NS step */
962 buf->bUpdateShifts = FALSE;
964 /* Now all nodes have all of the ED/flooding positions in edi->sav->xcoll,
965 * as well as the indices in edi->sav.anrs */
967 /* Fit the reference indices to the reference structure */
970 fit_to_reference(buf->xcoll, transvec, rotmat, edi);
974 fit_to_reference(buf->xc_ref, transvec, rotmat, edi);
977 /* Now apply the translation and rotation to the ED structure */
978 translate_and_rotate(buf->xcoll, edi->sav.nr, transvec, rotmat);
980 /* Project fitted structure onto supbspace -> store in edi->flood.vecs.xproj */
981 project_to_eigvectors(buf->xcoll, &edi->flood.vecs, *edi);
983 if (!edi->flood.bConstForce)
985 /* Compute Vfl(x) from flood.xproj */
986 edi->flood.Vfl = flood_energy(edi, step);
988 update_adaption(edi);
990 /* Compute the flooding forces */
994 /* Translate them into cartesian positions */
995 flood_blowup(*edi, edi->flood.forces_cartesian);
997 /* Rotate forces back so that they correspond to the given structure and not to the fitted one */
998 /* Each node rotates back its local forces */
999 transpose(rotmat, tmat);
1000 rotate_x(edi->flood.forces_cartesian, edi->sav.nr_loc, tmat);
1002 /* Finally add forces to the main force variable */
1003 for (i = 0; i < edi->sav.nr_loc; i++)
1005 rvec_inc(force[edi->sav.anrs_loc[i]], edi->flood.forces_cartesian[i]);
1008 /* Output is written by the master process */
1009 if (do_per_step(step, edi->outfrq) && MASTER(cr))
1011 /* Output how well we fit to the reference */
1014 /* Indices of reference and average structures are identical,
1015 * thus we can calculate the rmsd to SREF using xcoll */
1016 rmsdev = rmsd_from_structure(buf->xcoll, &edi->sref);
1020 /* We have to translate & rotate the reference atoms first */
1021 translate_and_rotate(buf->xc_ref, edi->sref.nr, transvec, rotmat);
1022 rmsdev = rmsd_from_structure(buf->xc_ref, &edi->sref);
1025 write_edo_flood(*edi, edo, rmsdev);
1030 /* Main flooding routine, called from do_force */
1031 void do_flood(const t_commrec* cr,
1032 const t_inputrec& ir,
1033 gmx::ArrayRef<const gmx::RVec> coords,
1034 gmx::ArrayRef<gmx::RVec> force,
1040 /* Write time to edo, when required. Output the time anyhow since we need
1041 * it in the output file for ED constraints. */
1042 if (MASTER(cr) && do_per_step(step, ed->edpar.begin()->outfrq))
1044 fprintf(ed->edo, "\n%12f", ir.init_t + step * ir.delta_t);
1047 if (ed->eEDtype != EssentialDynamicsType::Flooding)
1052 for (auto& edi : ed->edpar)
1054 /* Call flooding for one matrix */
1055 if (edi.flood.vecs.neig)
1057 do_single_flood(ed->edo, coords, force, &edi, step, box, cr, bNS);
1063 /* Called by init_edi, configure some flooding related variables and structures,
1064 * print headers to output files */
1065 static void init_flood(t_edpar* edi, gmx_edsam* ed, real dt)
1070 edi->flood.Efl = edi->flood.constEfl;
1074 if (edi->flood.vecs.neig)
1076 /* If in any of the ED groups we find a flooding vector, flooding is turned on */
1077 ed->eEDtype = EssentialDynamicsType::Flooding;
1080 "ED: Flooding %d eigenvector%s.\n",
1081 edi->flood.vecs.neig,
1082 edi->flood.vecs.neig > 1 ? "s" : "");
1084 if (edi->flood.bConstForce)
1086 /* We have used stpsz as a vehicle to carry the fproj values for constant
1087 * force flooding. Now we copy that to flood.vecs.fproj. Note that
1088 * in const force flooding, fproj is never changed. */
1089 for (i = 0; i < edi->flood.vecs.neig; i++)
1091 edi->flood.vecs.fproj[i] = edi->flood.vecs.stpsz[i];
1094 "ED: applying on eigenvector %d a constant force of %g\n",
1095 edi->flood.vecs.ieig[i],
1096 edi->flood.vecs.fproj[i]);
1104 /*********** Energy book keeping ******/
1105 static void get_flood_enx_names(t_edpar* edi, char** names, int* nnames) /* get header of energies */
1114 srenew(names, count);
1115 sprintf(buf, "Vfl_%d", count);
1116 names[count - 1] = gmx_strdup(buf);
1117 actual = actual->next_edi;
1120 *nnames = count - 1;
1124 static void get_flood_energies(t_edpar* edi, real Vfl[], int nnames)
1126 /*fl has to be big enough to capture nnames-many entries*/
1135 Vfl[count - 1] = actual->flood.Vfl;
1136 actual = actual->next_edi;
1139 if (nnames != count - 1)
1141 gmx_fatal(FARGS, "Number of energies is not consistent with t_edi structure");
1144 /************* END of FLOODING IMPLEMENTATION ****************************/
1148 /* This function opens the ED input and output files, reads in all datasets it finds
1149 * in the input file, and cross-checks whether the .edi file information is consistent
1150 * with the essential dynamics data found in the checkpoint file (if present).
1151 * gmx make_edi can be used to create an .edi input file.
1153 static std::unique_ptr<gmx::EssentialDynamics> ed_open(int natoms,
1154 ObservablesHistory* oh,
1155 const char* ediFileName,
1156 const char* edoFileName,
1157 const gmx::StartingBehavior startingBehavior,
1158 const gmx_output_env_t* oenv,
1159 const t_commrec* cr)
1161 auto edHandle = std::make_unique<gmx::EssentialDynamics>();
1162 auto* ed = edHandle->getLegacyED();
1163 /* We want to perform ED (this switch might later be upgraded to EssentialDynamicsType::Flooding) */
1164 ed->eEDtype = EssentialDynamicsType::EDSampling;
1168 // If we start from a checkpoint file, we already have an edsamHistory struct
1169 if (oh->edsamHistory == nullptr)
1171 oh->edsamHistory = std::make_unique<edsamhistory_t>(edsamhistory_t{});
1173 edsamhistory_t* EDstate = oh->edsamHistory.get();
1175 /* Read the edi input file: */
1176 ed->edpar = read_edi_file(ediFileName, natoms);
1178 /* Make sure the checkpoint was produced in a run using this .edi file */
1179 if (EDstate->bFromCpt)
1181 crosscheck_edi_file_vs_checkpoint(*ed, EDstate);
1185 EDstate->nED = ed->edpar.size();
1187 init_edsamstate(*ed, EDstate);
1189 /* The master opens the ED output file */
1190 if (startingBehavior == gmx::StartingBehavior::RestartWithAppending)
1192 ed->edo = gmx_fio_fopen(edoFileName, "a+");
1196 ed->edo = xvgropen(edoFileName,
1197 "Essential dynamics / flooding output",
1199 "RMSDs (nm), projections on EVs (nm), ...",
1202 /* Make a descriptive legend */
1203 write_edo_legend(ed, EDstate->nED, oenv);
1210 /* Broadcasts the structure data */
1211 static void bc_ed_positions(const t_commrec* cr, struct gmx_edx* s, EssentialDynamicsStructure stype)
1213 snew_bc(MASTER(cr), s->anrs, s->nr); /* Index numbers */
1214 snew_bc(MASTER(cr), s->x, s->nr); /* Positions */
1215 nblock_bc(cr->mpi_comm_mygroup, s->nr, s->anrs);
1216 nblock_bc(cr->mpi_comm_mygroup, s->nr, s->x);
1218 /* For the average & reference structures we need an array for the collective indices,
1219 * and we need to broadcast the masses as well */
1220 if (stype == EssentialDynamicsStructure::Average || stype == EssentialDynamicsStructure::Reference)
1222 /* We need these additional variables in the parallel case: */
1223 snew(s->c_ind, s->nr); /* Collective indices */
1224 /* Local atom indices get assigned in dd_make_local_group_indices.
1225 * There, also memory is allocated */
1226 s->nalloc_loc = 0; /* allocation size of s->anrs_loc */
1227 snew_bc(MASTER(cr), s->x_old, s->nr); /* To be able to always make the ED molecule whole, ... */
1228 nblock_bc(cr->mpi_comm_mygroup, s->nr, s->x_old); /* ... keep track of shift changes with the help of old coords */
1231 /* broadcast masses for the reference structure (for mass-weighted fitting) */
1232 if (stype == EssentialDynamicsStructure::Reference)
1234 snew_bc(MASTER(cr), s->m, s->nr);
1235 nblock_bc(cr->mpi_comm_mygroup, s->nr, s->m);
1238 /* For the average structure we might need the masses for mass-weighting */
1239 if (stype == EssentialDynamicsStructure::Average)
1241 snew_bc(MASTER(cr), s->sqrtm, s->nr);
1242 nblock_bc(cr->mpi_comm_mygroup, s->nr, s->sqrtm);
1243 snew_bc(MASTER(cr), s->m, s->nr);
1244 nblock_bc(cr->mpi_comm_mygroup, s->nr, s->m);
1249 /* Broadcasts the eigenvector data */
1250 static void bc_ed_vecs(const t_commrec* cr, t_eigvec* ev, int length)
1254 snew_bc(MASTER(cr), ev->ieig, ev->neig); /* index numbers of eigenvector */
1255 snew_bc(MASTER(cr), ev->stpsz, ev->neig); /* stepsizes per eigenvector */
1256 snew_bc(MASTER(cr), ev->xproj, ev->neig); /* instantaneous x projection */
1257 snew_bc(MASTER(cr), ev->fproj, ev->neig); /* instantaneous f projection */
1258 snew_bc(MASTER(cr), ev->refproj, ev->neig); /* starting or target projection */
1260 nblock_bc(cr->mpi_comm_mygroup, ev->neig, ev->ieig);
1261 nblock_bc(cr->mpi_comm_mygroup, ev->neig, ev->stpsz);
1262 nblock_bc(cr->mpi_comm_mygroup, ev->neig, ev->xproj);
1263 nblock_bc(cr->mpi_comm_mygroup, ev->neig, ev->fproj);
1264 nblock_bc(cr->mpi_comm_mygroup, ev->neig, ev->refproj);
1266 snew_bc(MASTER(cr), ev->vec, ev->neig); /* Eigenvector components */
1267 for (i = 0; i < ev->neig; i++)
1269 snew_bc(MASTER(cr), ev->vec[i], length);
1270 nblock_bc(cr->mpi_comm_mygroup, length, ev->vec[i]);
1275 /* Broadcasts the ED / flooding data to other nodes
1276 * and allocates memory where needed */
1277 static void broadcast_ed_data(const t_commrec* cr, gmx_edsam* ed)
1279 /* Master lets the other nodes know if its ED only or also flooding */
1280 gmx_bcast(sizeof(ed->eEDtype), &(ed->eEDtype), cr->mpi_comm_mygroup);
1282 int numedis = ed->edpar.size();
1283 /* First let everybody know how many ED data sets to expect */
1284 gmx_bcast(sizeof(numedis), &numedis, cr->mpi_comm_mygroup);
1285 nblock_abc(MASTER(cr), cr->mpi_comm_mygroup, numedis, &(ed->edpar));
1286 /* Now transfer the ED data set(s) */
1287 for (auto& edi : ed->edpar)
1289 /* Broadcast a single ED data set */
1290 block_bc(cr->mpi_comm_mygroup, edi);
1292 /* Broadcast positions */
1293 bc_ed_positions(cr, &(edi.sref), EssentialDynamicsStructure::Reference); /* reference positions (don't broadcast masses) */
1294 bc_ed_positions(cr, &(edi.sav), EssentialDynamicsStructure::Average); /* average positions (do broadcast masses as well) */
1295 bc_ed_positions(cr, &(edi.star), EssentialDynamicsStructure::Target); /* target positions */
1296 bc_ed_positions(cr, &(edi.sori), EssentialDynamicsStructure::Origin); /* origin positions */
1298 /* Broadcast eigenvectors */
1299 bc_ed_vecs(cr, &edi.vecs.mon, edi.sav.nr);
1300 bc_ed_vecs(cr, &edi.vecs.linfix, edi.sav.nr);
1301 bc_ed_vecs(cr, &edi.vecs.linacc, edi.sav.nr);
1302 bc_ed_vecs(cr, &edi.vecs.radfix, edi.sav.nr);
1303 bc_ed_vecs(cr, &edi.vecs.radacc, edi.sav.nr);
1304 bc_ed_vecs(cr, &edi.vecs.radcon, edi.sav.nr);
1305 /* Broadcast flooding eigenvectors and, if needed, values for the moving reference */
1306 bc_ed_vecs(cr, &edi.flood.vecs, edi.sav.nr);
1308 /* For harmonic restraints the reference projections can change with time */
1309 if (edi.flood.bHarmonic)
1311 snew_bc(MASTER(cr), edi.flood.initialReferenceProjection, edi.flood.vecs.neig);
1312 snew_bc(MASTER(cr), edi.flood.referenceProjectionSlope, edi.flood.vecs.neig);
1313 nblock_bc(cr->mpi_comm_mygroup, edi.flood.vecs.neig, edi.flood.initialReferenceProjection);
1314 nblock_bc(cr->mpi_comm_mygroup, edi.flood.vecs.neig, edi.flood.referenceProjectionSlope);
1320 /* init-routine called for every *.edi-cycle, initialises t_edpar structure */
1321 static void init_edi(const gmx_mtop_t& mtop, t_edpar* edi)
1324 real totalmass = 0.0;
1327 /* NOTE Init_edi is executed on the master process only
1328 * The initialized data sets are then transmitted to the
1329 * other nodes in broadcast_ed_data */
1331 /* evaluate masses (reference structure) */
1332 snew(edi->sref.m, edi->sref.nr);
1334 for (i = 0; i < edi->sref.nr; i++)
1338 edi->sref.m[i] = mtopGetAtomMass(mtop, edi->sref.anrs[i], &molb);
1342 edi->sref.m[i] = 1.0;
1345 /* Check that every m > 0. Bad things will happen otherwise. */
1346 if (edi->sref.m[i] <= 0.0)
1349 "Reference structure atom %d (sam.edi index %d) has a mass of %g.\n"
1350 "For a mass-weighted fit, all reference structure atoms need to have a mass "
1352 "Either make the covariance analysis non-mass-weighted, or exclude massless\n"
1353 "atoms from the reference structure by creating a proper index group.\n",
1355 edi->sref.anrs[i] + 1,
1359 totalmass += edi->sref.m[i];
1361 edi->sref.mtot = totalmass;
1363 /* Masses m and sqrt(m) for the average structure. Note that m
1364 * is needed if forces have to be evaluated in do_edsam */
1365 snew(edi->sav.sqrtm, edi->sav.nr);
1366 snew(edi->sav.m, edi->sav.nr);
1367 for (i = 0; i < edi->sav.nr; i++)
1369 edi->sav.m[i] = mtopGetAtomMass(mtop, edi->sav.anrs[i], &molb);
1372 edi->sav.sqrtm[i] = sqrt(edi->sav.m[i]);
1376 edi->sav.sqrtm[i] = 1.0;
1379 /* Check that every m > 0. Bad things will happen otherwise. */
1380 if (edi->sav.sqrtm[i] <= 0.0)
1383 "Average structure atom %d (sam.edi index %d) has a mass of %g.\n"
1384 "For ED with mass-weighting, all average structure atoms need to have a mass "
1386 "Either make the covariance analysis non-mass-weighted, or exclude massless\n"
1387 "atoms from the average structure by creating a proper index group.\n",
1389 edi->sav.anrs[i] + 1,
1394 /* put reference structure in origin */
1395 get_center(edi->sref.x, edi->sref.m, edi->sref.nr, com);
1399 translate_x(edi->sref.x, edi->sref.nr, com);
1401 /* Init ED buffer */
1406 static void check(const char* line, const char* label)
1408 if (!strstr(line, label))
1411 "Could not find input parameter %s at expected position in edsam input-file "
1412 "(.edi)\nline read instead is %s",
1419 static int read_checked_edint(FILE* file, const char* label)
1421 char line[STRLEN + 1];
1424 fgets2(line, STRLEN, file);
1426 fgets2(line, STRLEN, file);
1427 sscanf(line, max_ev_fmt_d, &idum);
1431 static bool read_checked_edbool(FILE* file, const char* label)
1433 return read_checked_edint(file, label) != 0;
1436 static int read_edint(FILE* file, bool* bEOF)
1438 char line[STRLEN + 1];
1443 eof = fgets2(line, STRLEN, file);
1449 eof = fgets2(line, STRLEN, file);
1455 sscanf(line, max_ev_fmt_d, &idum);
1461 static real read_checked_edreal(FILE* file, const char* label)
1463 char line[STRLEN + 1];
1467 fgets2(line, STRLEN, file);
1469 fgets2(line, STRLEN, file);
1470 sscanf(line, max_ev_fmt_lf, &rdum);
1471 return static_cast<real>(rdum); /* always read as double and convert to single */
1475 static void read_edx(FILE* file, int number, int* anrs, rvec* x)
1478 char line[STRLEN + 1];
1482 for (i = 0; i < number; i++)
1484 fgets2(line, STRLEN, file);
1485 sscanf(line, max_ev_fmt_dlflflf, &anrs[i], &d[0], &d[1], &d[2]);
1486 anrs[i]--; /* we are reading FORTRAN indices */
1487 for (j = 0; j < 3; j++)
1489 x[i][j] = d[j]; /* always read as double and convert to single */
1496 /*!\brief Read eigenvector coordinates for multiple eigenvectors from a file.
1497 * \param[in] in the file to read from
1498 * \param[in] numAtoms the number of atoms/coordinates for the eigenvector
1499 * \param[out] vec the eigen-vectors
1500 * \param[in] nEig the number of eigenvectors
1502 void scan_edvec(FILE* in, int numAtoms, rvec*** vec, int nEig)
1505 for (int iEigenvector = 0; iEigenvector < nEig; iEigenvector++)
1507 snew((*vec)[iEigenvector], numAtoms);
1508 for (int iAtom = 0; iAtom < numAtoms; iAtom++)
1510 char line[STRLEN + 1];
1512 fgets2(line, STRLEN, in);
1513 sscanf(line, max_ev_fmt_lelele, &x, &y, &z);
1514 (*vec)[iEigenvector][iAtom][XX] = x;
1515 (*vec)[iEigenvector][iAtom][YY] = y;
1516 (*vec)[iEigenvector][iAtom][ZZ] = z;
1520 /*!\brief Read an essential dynamics eigenvector and corresponding step size.
1521 * \param[in] in input file
1522 * \param[in] nrAtoms number of atoms/coordinates
1523 * \param[out] tvec the eigenvector
1525 void read_edvec(FILE* in, int nrAtoms, t_eigvec* tvec)
1527 tvec->neig = read_checked_edint(in, "NUMBER OF EIGENVECTORS");
1528 if (tvec->neig <= 0)
1533 snew(tvec->ieig, tvec->neig);
1534 snew(tvec->stpsz, tvec->neig);
1535 for (int i = 0; i < tvec->neig; i++)
1537 char line[STRLEN + 1];
1538 fgets2(line, STRLEN, in);
1539 int numEigenVectors;
1541 const int nscan = sscanf(line, max_ev_fmt_dlf, &numEigenVectors, &stepSize);
1544 gmx_fatal(FARGS, "Expected 2 values for flooding vec: <nr> <stpsz>\n");
1546 tvec->ieig[i] = numEigenVectors;
1547 tvec->stpsz[i] = stepSize;
1548 } /* end of loop over eigenvectors */
1550 scan_edvec(in, nrAtoms, &tvec->vec, tvec->neig);
1552 /*!\brief Read an essential dynamics eigenvector and intial reference projections and slopes if available.
1554 * Eigenvector and its intial reference and slope are stored on the
1555 * same line in the .edi format. To avoid re-winding the .edi file,
1556 * the reference eigen-vector and reference data are read in one go.
1558 * \param[in] in input file
1559 * \param[in] nrAtoms number of atoms/coordinates
1560 * \param[out] tvec the eigenvector
1561 * \param[out] initialReferenceProjection The projection onto eigenvectors as read from file.
1562 * \param[out] referenceProjectionSlope The slope of the reference projections.
1564 bool readEdVecWithReferenceProjection(FILE* in,
1567 real** initialReferenceProjection,
1568 real** referenceProjectionSlope)
1570 bool providesReference = false;
1571 tvec->neig = read_checked_edint(in, "NUMBER OF EIGENVECTORS");
1572 if (tvec->neig <= 0)
1577 snew(tvec->ieig, tvec->neig);
1578 snew(tvec->stpsz, tvec->neig);
1579 snew(*initialReferenceProjection, tvec->neig);
1580 snew(*referenceProjectionSlope, tvec->neig);
1581 for (int i = 0; i < tvec->neig; i++)
1583 char line[STRLEN + 1];
1584 fgets2(line, STRLEN, in);
1585 int numEigenVectors;
1586 double stepSize = 0.;
1587 double referenceProjection = 0.;
1588 double referenceSlope = 0.;
1589 const int nscan = sscanf(
1590 line, max_ev_fmt_dlflflf, &numEigenVectors, &stepSize, &referenceProjection, &referenceSlope);
1591 /* Zero out values which were not scanned */
1595 /* Every 4 values read, including reference position */
1596 providesReference = true;
1599 /* A reference position is provided */
1600 providesReference = true;
1601 /* No value for slope, set to 0 */
1602 referenceSlope = 0.0;
1605 /* No values for reference projection and slope, set to 0 */
1606 referenceProjection = 0.0;
1607 referenceSlope = 0.0;
1611 "Expected 2 - 4 (not %d) values for flooding vec: <nr> <spring const> "
1612 "<refproj> <refproj-slope>\n",
1615 (*initialReferenceProjection)[i] = referenceProjection;
1616 (*referenceProjectionSlope)[i] = referenceSlope;
1618 tvec->ieig[i] = numEigenVectors;
1619 tvec->stpsz[i] = stepSize;
1620 } /* end of loop over eigenvectors */
1622 scan_edvec(in, nrAtoms, &tvec->vec, tvec->neig);
1623 return providesReference;
1626 /*!\brief Allocate working memory for the eigenvectors.
1627 * \param[in,out] tvec eigenvector for which memory will be allocated
1629 void setup_edvec(t_eigvec* tvec)
1631 snew(tvec->xproj, tvec->neig);
1632 snew(tvec->fproj, tvec->neig);
1633 snew(tvec->refproj, tvec->neig);
1638 /* Check if the same atom indices are used for reference and average positions */
1639 static gmx_bool check_if_same(struct gmx_edx sref, struct gmx_edx sav)
1644 /* If the number of atoms differs between the two structures,
1645 * they cannot be identical */
1646 if (sref.nr != sav.nr)
1651 /* Now that we know that both stuctures have the same number of atoms,
1652 * check if also the indices are identical */
1653 for (i = 0; i < sav.nr; i++)
1655 if (sref.anrs[i] != sav.anrs[i])
1661 "ED: Note: Reference and average structure are composed of the same atom indices.\n");
1669 //! Oldest (lowest) magic number indicating unsupported essential dynamics input
1670 constexpr int c_oldestUnsupportedMagicNumber = 666;
1671 //! Oldest (lowest) magic number indicating supported essential dynamics input
1672 constexpr int c_oldestSupportedMagicNumber = 669;
1673 //! Latest (highest) magic number indicating supported essential dynamics input
1674 constexpr int c_latestSupportedMagicNumber = 670;
1676 /*!\brief Set up essential dynamics work parameters.
1677 * \param[in] edi Essential dynamics working structure.
1679 void setup_edi(t_edpar* edi)
1681 snew(edi->sref.x_old, edi->sref.nr);
1682 edi->sref.sqrtm = nullptr;
1683 snew(edi->sav.x_old, edi->sav.nr);
1684 if (edi->star.nr > 0)
1686 edi->star.sqrtm = nullptr;
1688 if (edi->sori.nr > 0)
1690 edi->sori.sqrtm = nullptr;
1692 setup_edvec(&edi->vecs.linacc);
1693 setup_edvec(&edi->vecs.mon);
1694 setup_edvec(&edi->vecs.linfix);
1695 setup_edvec(&edi->vecs.linacc);
1696 setup_edvec(&edi->vecs.radfix);
1697 setup_edvec(&edi->vecs.radacc);
1698 setup_edvec(&edi->vecs.radcon);
1699 setup_edvec(&edi->flood.vecs);
1702 /*!\brief Check if edi file version supports CONST_FORCE_FLOODING.
1703 * \param[in] magicNumber indicates the essential dynamics input file version
1704 * \returns true if CONST_FORCE_FLOODING is supported
1706 bool ediFileHasConstForceFlooding(int magicNumber)
1708 return magicNumber > c_oldestSupportedMagicNumber;
1711 /*!\brief Reports reading success of the essential dynamics input file magic number.
1712 * \param[in] in pointer to input file
1713 * \param[out] magicNumber determines the edi file version
1714 * \returns true if setting file version from input file was successful.
1716 bool ediFileHasValidDataSet(FILE* in, int* magicNumber)
1718 /* the edi file is not free format, so expect problems if the input is corrupt. */
1719 bool reachedEndOfFile = true;
1720 /* check the magic number */
1721 *magicNumber = read_edint(in, &reachedEndOfFile);
1722 /* Check whether we have reached the end of the input file */
1723 return !reachedEndOfFile;
1726 /*!\brief Trigger fatal error if magic number is unsupported.
1727 * \param[in] magicNumber A magic number read from the edi file
1728 * \param[in] fn name of input file for error reporting
1730 void exitWhenMagicNumberIsInvalid(int magicNumber, const char* fn)
1733 if (magicNumber < c_oldestSupportedMagicNumber || magicNumber > c_latestSupportedMagicNumber)
1735 if (magicNumber >= c_oldestUnsupportedMagicNumber && magicNumber < c_oldestSupportedMagicNumber)
1738 "Wrong magic number: Use newest version of make_edi to produce edi file");
1742 gmx_fatal(FARGS, "Wrong magic number %d in %s", magicNumber, fn);
1747 /*!\brief reads an essential dynamics input file into a essential dynamics data structure.
1749 * \param[in] in input file
1750 * \param[in] nr_mdatoms the number of md atoms, used for consistency checking
1751 * \param[in] hasConstForceFlooding determines if field "CONST_FORCE_FLOODING" is available in input file
1752 * \param[in] fn the file name of the input file for error reporting
1753 * \returns edi essential dynamics parameters
1755 t_edpar read_edi(FILE* in, int nr_mdatoms, bool hasConstForceFlooding, const char* fn)
1759 /* check the number of atoms */
1760 edi.nini = read_edint(in, &bEOF);
1761 if (edi.nini != nr_mdatoms)
1763 gmx_fatal(FARGS, "Nr of atoms in %s (%d) does not match nr of md atoms (%d)", fn, edi.nini, nr_mdatoms);
1766 /* Done checking. For the rest we blindly trust the input */
1767 edi.fitmas = read_checked_edbool(in, "FITMAS");
1768 edi.pcamas = read_checked_edbool(in, "ANALYSIS_MAS");
1769 edi.outfrq = read_checked_edint(in, "OUTFRQ");
1770 edi.maxedsteps = read_checked_edint(in, "MAXLEN");
1771 edi.slope = read_checked_edreal(in, "SLOPECRIT");
1773 edi.presteps = read_checked_edint(in, "PRESTEPS");
1774 edi.flood.deltaF0 = read_checked_edreal(in, "DELTA_F0");
1775 edi.flood.deltaF = read_checked_edreal(in, "INIT_DELTA_F");
1776 edi.flood.tau = read_checked_edreal(in, "TAU");
1777 edi.flood.constEfl = read_checked_edreal(in, "EFL_NULL");
1778 edi.flood.alpha2 = read_checked_edreal(in, "ALPHA2");
1779 edi.flood.kT = read_checked_edreal(in, "KT");
1780 edi.flood.bHarmonic = read_checked_edbool(in, "HARMONIC");
1781 if (hasConstForceFlooding)
1783 edi.flood.bConstForce = read_checked_edbool(in, "CONST_FORCE_FLOODING");
1787 edi.flood.bConstForce = FALSE;
1789 edi.sref.nr = read_checked_edint(in, "NREF");
1791 /* allocate space for reference positions and read them */
1792 snew(edi.sref.anrs, edi.sref.nr);
1793 snew(edi.sref.x, edi.sref.nr);
1794 read_edx(in, edi.sref.nr, edi.sref.anrs, edi.sref.x);
1796 /* average positions. they define which atoms will be used for ED sampling */
1797 edi.sav.nr = read_checked_edint(in, "NAV");
1798 snew(edi.sav.anrs, edi.sav.nr);
1799 snew(edi.sav.x, edi.sav.nr);
1800 read_edx(in, edi.sav.nr, edi.sav.anrs, edi.sav.x);
1802 /* Check if the same atom indices are used for reference and average positions */
1803 edi.bRefEqAv = check_if_same(edi.sref, edi.sav);
1807 read_edvec(in, edi.sav.nr, &edi.vecs.mon);
1808 read_edvec(in, edi.sav.nr, &edi.vecs.linfix);
1809 read_edvec(in, edi.sav.nr, &edi.vecs.linacc);
1810 read_edvec(in, edi.sav.nr, &edi.vecs.radfix);
1811 read_edvec(in, edi.sav.nr, &edi.vecs.radacc);
1812 read_edvec(in, edi.sav.nr, &edi.vecs.radcon);
1814 /* Was a specific reference point for the flooding/umbrella potential provided in the edi file? */
1815 bool bHaveReference = false;
1816 if (edi.flood.bHarmonic)
1818 bHaveReference = readEdVecWithReferenceProjection(in,
1821 &edi.flood.initialReferenceProjection,
1822 &edi.flood.referenceProjectionSlope);
1826 read_edvec(in, edi.sav.nr, &edi.flood.vecs);
1829 /* target positions */
1830 edi.star.nr = read_edint(in, &bEOF);
1831 if (edi.star.nr > 0)
1833 snew(edi.star.anrs, edi.star.nr);
1834 snew(edi.star.x, edi.star.nr);
1835 read_edx(in, edi.star.nr, edi.star.anrs, edi.star.x);
1838 /* positions defining origin of expansion circle */
1839 edi.sori.nr = read_edint(in, &bEOF);
1840 if (edi.sori.nr > 0)
1844 /* Both an -ori structure and a at least one manual reference point have been
1845 * specified. That's ambiguous and probably not intentional. */
1847 "ED: An origin structure has been provided and a at least one (moving) "
1849 " point was manually specified in the edi file. That is ambiguous. "
1852 snew(edi.sori.anrs, edi.sori.nr);
1853 snew(edi.sori.x, edi.sori.nr);
1854 read_edx(in, edi.sori.nr, edi.sori.anrs, edi.sori.x);
1859 std::vector<t_edpar> read_edi_file(const char* fn, int nr_mdatoms)
1861 std::vector<t_edpar> essentialDynamicsParameters;
1863 /* This routine is executed on the master only */
1865 /* Open the .edi parameter input file */
1866 in = gmx_fio_fopen(fn, "r");
1867 fprintf(stderr, "ED: Reading edi file %s\n", fn);
1869 /* Now read a sequence of ED input parameter sets from the edi file */
1870 int ediFileMagicNumber;
1871 while (ediFileHasValidDataSet(in, &ediFileMagicNumber))
1873 exitWhenMagicNumberIsInvalid(ediFileMagicNumber, fn);
1874 bool hasConstForceFlooding = ediFileHasConstForceFlooding(ediFileMagicNumber);
1875 auto edi = read_edi(in, nr_mdatoms, hasConstForceFlooding, fn);
1877 essentialDynamicsParameters.emplace_back(edi);
1879 /* Since we arrived within this while loop we know that there is still another data set to be read in */
1880 /* We need to allocate space for the data: */
1882 if (essentialDynamicsParameters.empty())
1884 gmx_fatal(FARGS, "No complete ED data set found in edi file %s.", fn);
1888 "ED: Found %zu ED group%s.\n",
1889 essentialDynamicsParameters.size(),
1890 essentialDynamicsParameters.size() > 1 ? "s" : "");
1892 /* Close the .edi file again */
1895 return essentialDynamicsParameters;
1897 } // anonymous namespace
1902 rvec* xcopy; /* Working copy of the positions in fit_to_reference */
1905 /* Fit the current positions to the reference positions
1906 * Do not actually do the fit, just return rotation and translation.
1907 * Note that the COM of the reference structure was already put into
1908 * the origin by init_edi. */
1909 static void fit_to_reference(rvec* xcoll, /* The positions to be fitted */
1910 rvec transvec, /* The translation vector */
1911 matrix rotmat, /* The rotation matrix */
1912 t_edpar* edi) /* Just needed for do_edfit */
1914 rvec com; /* center of mass */
1916 struct t_fit_to_ref* loc;
1919 /* Allocate memory the first time this routine is called for each edi group */
1920 if (nullptr == edi->buf->fit_to_ref)
1922 snew(edi->buf->fit_to_ref, 1);
1923 snew(edi->buf->fit_to_ref->xcopy, edi->sref.nr);
1925 loc = edi->buf->fit_to_ref;
1927 /* We do not touch the original positions but work on a copy. */
1928 for (i = 0; i < edi->sref.nr; i++)
1930 copy_rvec(xcoll[i], loc->xcopy[i]);
1933 /* Calculate the center of mass */
1934 get_center(loc->xcopy, edi->sref.m, edi->sref.nr, com);
1936 transvec[XX] = -com[XX];
1937 transvec[YY] = -com[YY];
1938 transvec[ZZ] = -com[ZZ];
1940 /* Subtract the center of mass from the copy */
1941 translate_x(loc->xcopy, edi->sref.nr, transvec);
1943 /* Determine the rotation matrix */
1944 do_edfit(edi->sref.nr, edi->sref.x, loc->xcopy, rotmat, edi);
1948 static void translate_and_rotate(rvec* x, /* The positions to be translated and rotated */
1949 int nat, /* How many positions are there? */
1950 rvec transvec, /* The translation vector */
1951 matrix rotmat) /* The rotation matrix */
1954 translate_x(x, nat, transvec);
1957 rotate_x(x, nat, rotmat);
1961 /* Gets the rms deviation of the positions to the structure s */
1962 /* fit_to_structure has to be called before calling this routine! */
1963 static real rmsd_from_structure(rvec* x, /* The positions under consideration */
1964 struct gmx_edx* s) /* The structure from which the rmsd shall be computed */
1970 for (i = 0; i < s->nr; i++)
1972 rmsd += distance2(s->x[i], x[i]);
1975 rmsd /= static_cast<real>(s->nr);
1982 void dd_make_local_ed_indices(gmx_domdec_t* dd, struct gmx_edsam* ed)
1984 if (ed->eEDtype != EssentialDynamicsType::None)
1986 /* Loop over ED groups */
1988 for (auto& edi : ed->edpar)
1990 /* Local atoms of the reference structure (for fitting), need only be assembled
1991 * if their indices differ from the average ones */
1994 dd_make_local_group_indices(dd->ga2la,
1999 &edi.sref.nalloc_loc,
2003 /* Local atoms of the average structure (on these ED will be performed) */
2004 dd_make_local_group_indices(dd->ga2la,
2009 &edi.sav.nalloc_loc,
2012 /* Indicate that the ED shift vectors for this structure need to be updated
2013 * at the next call to communicate_group_positions, since obviously we are in a NS step */
2014 edi.buf->do_edsam->bUpdateShifts = TRUE;
2020 static inline void ed_unshift_single_coord(const matrix box, const rvec x, const ivec is, rvec xu)
2031 xu[XX] = x[XX] - tx * box[XX][XX] - ty * box[YY][XX] - tz * box[ZZ][XX];
2032 xu[YY] = x[YY] - ty * box[YY][YY] - tz * box[ZZ][YY];
2033 xu[ZZ] = x[ZZ] - tz * box[ZZ][ZZ];
2037 xu[XX] = x[XX] - tx * box[XX][XX];
2038 xu[YY] = x[YY] - ty * box[YY][YY];
2039 xu[ZZ] = x[ZZ] - tz * box[ZZ][ZZ];
2045 /*!\brief Apply fixed linear constraints to essential dynamics variable.
2046 * \param[in,out] xcoll The collected coordinates.
2047 * \param[in] edi the essential dynamics parameters
2048 * \param[in] step the current simulation step
2050 void do_linfix(rvec* xcoll, const t_edpar& edi, int64_t step)
2052 /* loop over linfix vectors */
2053 for (int i = 0; i < edi.vecs.linfix.neig; i++)
2055 /* calculate the projection */
2056 real proj = projectx(edi, xcoll, edi.vecs.linfix.vec[i]);
2058 /* calculate the correction */
2059 real preFactor = edi.vecs.linfix.refproj[i] + step * edi.vecs.linfix.stpsz[i] - proj;
2061 /* apply the correction */
2062 preFactor /= edi.sav.sqrtm[i];
2063 for (int j = 0; j < edi.sav.nr; j++)
2065 rvec differenceVector;
2066 svmul(preFactor, edi.vecs.linfix.vec[i][j], differenceVector);
2067 rvec_inc(xcoll[j], differenceVector);
2072 /*!\brief Apply acceptance linear constraints to essential dynamics variable.
2073 * \param[in,out] xcoll The collected coordinates.
2074 * \param[in] edi the essential dynamics parameters
2076 void do_linacc(rvec* xcoll, t_edpar* edi)
2078 /* loop over linacc vectors */
2079 for (int i = 0; i < edi->vecs.linacc.neig; i++)
2081 /* calculate the projection */
2082 real proj = projectx(*edi, xcoll, edi->vecs.linacc.vec[i]);
2084 /* calculate the correction */
2085 real preFactor = 0.0;
2086 if (edi->vecs.linacc.stpsz[i] > 0.0)
2088 if ((proj - edi->vecs.linacc.refproj[i]) < 0.0)
2090 preFactor = edi->vecs.linacc.refproj[i] - proj;
2093 if (edi->vecs.linacc.stpsz[i] < 0.0)
2095 if ((proj - edi->vecs.linacc.refproj[i]) > 0.0)
2097 preFactor = edi->vecs.linacc.refproj[i] - proj;
2101 /* apply the correction */
2102 preFactor /= edi->sav.sqrtm[i];
2103 for (int j = 0; j < edi->sav.nr; j++)
2105 rvec differenceVector;
2106 svmul(preFactor, edi->vecs.linacc.vec[i][j], differenceVector);
2107 rvec_inc(xcoll[j], differenceVector);
2110 /* new positions will act as reference */
2111 edi->vecs.linacc.refproj[i] = proj + preFactor;
2117 static void do_radfix(rvec* xcoll, t_edpar* edi)
2120 real *proj, rad = 0.0, ratio;
2124 if (edi->vecs.radfix.neig == 0)
2129 snew(proj, edi->vecs.radfix.neig);
2131 /* loop over radfix vectors */
2132 for (i = 0; i < edi->vecs.radfix.neig; i++)
2134 /* calculate the projections, radius */
2135 proj[i] = projectx(*edi, xcoll, edi->vecs.radfix.vec[i]);
2136 rad += gmx::square(proj[i] - edi->vecs.radfix.refproj[i]);
2140 ratio = (edi->vecs.radfix.stpsz[0] + edi->vecs.radfix.radius) / rad - 1.0;
2141 edi->vecs.radfix.radius += edi->vecs.radfix.stpsz[0];
2143 /* loop over radfix vectors */
2144 for (i = 0; i < edi->vecs.radfix.neig; i++)
2146 proj[i] -= edi->vecs.radfix.refproj[i];
2148 /* apply the correction */
2149 proj[i] /= edi->sav.sqrtm[i];
2151 for (j = 0; j < edi->sav.nr; j++)
2153 svmul(proj[i], edi->vecs.radfix.vec[i][j], vec_dum);
2154 rvec_inc(xcoll[j], vec_dum);
2162 static void do_radacc(rvec* xcoll, t_edpar* edi)
2165 real *proj, rad = 0.0, ratio = 0.0;
2169 if (edi->vecs.radacc.neig == 0)
2174 snew(proj, edi->vecs.radacc.neig);
2176 /* loop over radacc vectors */
2177 for (i = 0; i < edi->vecs.radacc.neig; i++)
2179 /* calculate the projections, radius */
2180 proj[i] = projectx(*edi, xcoll, edi->vecs.radacc.vec[i]);
2181 rad += gmx::square(proj[i] - edi->vecs.radacc.refproj[i]);
2185 /* only correct when radius decreased */
2186 if (rad < edi->vecs.radacc.radius)
2188 ratio = edi->vecs.radacc.radius / rad - 1.0;
2192 edi->vecs.radacc.radius = rad;
2195 /* loop over radacc vectors */
2196 for (i = 0; i < edi->vecs.radacc.neig; i++)
2198 proj[i] -= edi->vecs.radacc.refproj[i];
2200 /* apply the correction */
2201 proj[i] /= edi->sav.sqrtm[i];
2203 for (j = 0; j < edi->sav.nr; j++)
2205 svmul(proj[i], edi->vecs.radacc.vec[i][j], vec_dum);
2206 rvec_inc(xcoll[j], vec_dum);
2218 static void do_radcon(rvec* xcoll, t_edpar* edi)
2221 real rad = 0.0, ratio = 0.0;
2222 struct t_do_radcon* loc;
2227 if (edi->buf->do_radcon != nullptr)
2234 snew(edi->buf->do_radcon, 1);
2236 loc = edi->buf->do_radcon;
2238 if (edi->vecs.radcon.neig == 0)
2245 snew(loc->proj, edi->vecs.radcon.neig);
2248 /* loop over radcon vectors */
2249 for (i = 0; i < edi->vecs.radcon.neig; i++)
2251 /* calculate the projections, radius */
2252 loc->proj[i] = projectx(*edi, xcoll, edi->vecs.radcon.vec[i]);
2253 rad += gmx::square(loc->proj[i] - edi->vecs.radcon.refproj[i]);
2256 /* only correct when radius increased */
2257 if (rad > edi->vecs.radcon.radius)
2259 ratio = edi->vecs.radcon.radius / rad - 1.0;
2261 /* loop over radcon vectors */
2262 for (i = 0; i < edi->vecs.radcon.neig; i++)
2264 /* apply the correction */
2265 loc->proj[i] -= edi->vecs.radcon.refproj[i];
2266 loc->proj[i] /= edi->sav.sqrtm[i];
2267 loc->proj[i] *= ratio;
2269 for (j = 0; j < edi->sav.nr; j++)
2271 svmul(loc->proj[i], edi->vecs.radcon.vec[i][j], vec_dum);
2272 rvec_inc(xcoll[j], vec_dum);
2278 edi->vecs.radcon.radius = rad;
2283 static void ed_apply_constraints(rvec* xcoll, t_edpar* edi, int64_t step)
2288 /* subtract the average positions */
2289 for (i = 0; i < edi->sav.nr; i++)
2291 rvec_dec(xcoll[i], edi->sav.x[i]);
2294 /* apply the constraints */
2297 do_linfix(xcoll, *edi, step);
2299 do_linacc(xcoll, edi);
2302 do_radfix(xcoll, edi);
2304 do_radacc(xcoll, edi);
2305 do_radcon(xcoll, edi);
2307 /* add back the average positions */
2308 for (i = 0; i < edi->sav.nr; i++)
2310 rvec_inc(xcoll[i], edi->sav.x[i]);
2317 /*!\brief Write out the projections onto the eigenvectors.
2318 * The order of output corresponds to ed_output_legend().
2319 * \param[in] edi The essential dyanmics parameters
2320 * \param[in] fp The output file
2321 * \param[in] rmsd the rmsd to the reference structure
2323 void write_edo(const t_edpar& edi, FILE* fp, real rmsd)
2325 /* Output how well we fit to the reference structure */
2326 fprintf(fp, EDcol_ffmt, rmsd);
2328 for (int i = 0; i < edi.vecs.mon.neig; i++)
2330 fprintf(fp, EDcol_efmt, edi.vecs.mon.xproj[i]);
2333 for (int i = 0; i < edi.vecs.linfix.neig; i++)
2335 fprintf(fp, EDcol_efmt, edi.vecs.linfix.xproj[i]);
2338 for (int i = 0; i < edi.vecs.linacc.neig; i++)
2340 fprintf(fp, EDcol_efmt, edi.vecs.linacc.xproj[i]);
2343 for (int i = 0; i < edi.vecs.radfix.neig; i++)
2345 fprintf(fp, EDcol_efmt, edi.vecs.radfix.xproj[i]);
2347 if (edi.vecs.radfix.neig)
2349 fprintf(fp, EDcol_ffmt, calc_radius(edi.vecs.radfix)); /* fixed increment radius */
2352 for (int i = 0; i < edi.vecs.radacc.neig; i++)
2354 fprintf(fp, EDcol_efmt, edi.vecs.radacc.xproj[i]);
2356 if (edi.vecs.radacc.neig)
2358 fprintf(fp, EDcol_ffmt, calc_radius(edi.vecs.radacc)); /* acceptance radius */
2361 for (int i = 0; i < edi.vecs.radcon.neig; i++)
2363 fprintf(fp, EDcol_efmt, edi.vecs.radcon.xproj[i]);
2365 if (edi.vecs.radcon.neig)
2367 fprintf(fp, EDcol_ffmt, calc_radius(edi.vecs.radcon)); /* contracting radius */
2373 /* Returns if any constraints are switched on */
2374 static bool ed_constraints(EssentialDynamicsType edtype, const t_edpar& edi)
2376 if (edtype == EssentialDynamicsType::EDSampling || edtype == EssentialDynamicsType::Flooding)
2378 return ((edi.vecs.linfix.neig != 0) || (edi.vecs.linacc.neig != 0) || (edi.vecs.radfix.neig != 0)
2379 || (edi.vecs.radacc.neig != 0) || (edi.vecs.radcon.neig != 0));
2385 /* Copies reference projection 'refproj' to fixed 'initialReferenceProjection' variable for
2386 * flooding/ umbrella sampling simulations. */
2387 static void copyEvecReference(t_eigvec* floodvecs, real* initialReferenceProjection)
2392 if (nullptr == initialReferenceProjection)
2394 snew(initialReferenceProjection, floodvecs->neig);
2397 for (i = 0; i < floodvecs->neig; i++)
2399 initialReferenceProjection[i] = floodvecs->refproj[i];
2404 /* Call on MASTER only. Check whether the essential dynamics / flooding
2405 * groups of the checkpoint file are consistent with the provided .edi file. */
2406 static void crosscheck_edi_file_vs_checkpoint(const gmx_edsam& ed, edsamhistory_t* EDstate)
2408 if (nullptr == EDstate->nref || nullptr == EDstate->nav)
2411 "Essential dynamics and flooding can only be switched on (or off) at the\n"
2412 "start of a new simulation. If a simulation runs with/without ED constraints,\n"
2413 "it must also continue with/without ED constraints when checkpointing.\n"
2414 "To switch on (or off) ED constraints, please prepare a new .tpr to start\n"
2415 "from without a checkpoint.\n");
2418 for (size_t edinum = 0; edinum < ed.edpar.size(); ++edinum)
2420 /* Check number of atoms in the reference and average structures */
2421 if (EDstate->nref[edinum] != ed.edpar[edinum].sref.nr)
2424 "The number of reference structure atoms in ED group %c is\n"
2425 "not the same in .cpt (NREF=%d) and .edi (NREF=%d) files!\n",
2426 get_EDgroupChar(edinum + 1, 0),
2427 EDstate->nref[edinum],
2428 ed.edpar[edinum].sref.nr);
2430 if (EDstate->nav[edinum] != ed.edpar[edinum].sav.nr)
2433 "The number of average structure atoms in ED group %c is\n"
2434 "not the same in .cpt (NREF=%d) and .edi (NREF=%d) files!\n",
2435 get_EDgroupChar(edinum + 1, 0),
2436 EDstate->nav[edinum],
2437 ed.edpar[edinum].sav.nr);
2441 if (gmx::ssize(ed.edpar) != EDstate->nED)
2444 "The number of essential dynamics / flooding groups is not consistent.\n"
2445 "There are %d ED groups in the .cpt file, but %zu in the .edi file!\n"
2446 "Are you sure this is the correct .edi file?\n",
2453 /* The edsamstate struct stores the information we need to make the ED group
2454 * whole again after restarts from a checkpoint file. Here we do the following:
2455 * a) If we did not start from .cpt, we prepare the struct for proper .cpt writing,
2456 * b) if we did start from .cpt, we copy over the last whole structures from .cpt,
2457 * c) in any case, for subsequent checkpoint writing, we set the pointers in
2458 * edsamstate to the x_old arrays, which contain the correct PBC representation of
2459 * all ED structures at the last time step. */
2460 static void init_edsamstate(const gmx_edsam& ed, edsamhistory_t* EDstate)
2462 snew(EDstate->old_sref_p, EDstate->nED);
2463 snew(EDstate->old_sav_p, EDstate->nED);
2465 /* If we did not read in a .cpt file, these arrays are not yet allocated */
2466 if (!EDstate->bFromCpt)
2468 snew(EDstate->nref, EDstate->nED);
2469 snew(EDstate->nav, EDstate->nED);
2472 /* Loop over all ED/flooding data sets (usually only one, though) */
2473 for (int nr_edi = 0; nr_edi < EDstate->nED; nr_edi++)
2475 const auto& edi = ed.edpar[nr_edi];
2476 /* We always need the last reference and average positions such that
2477 * in the next time step we can make the ED group whole again
2478 * if the atoms do not have the correct PBC representation */
2479 if (EDstate->bFromCpt)
2481 /* Copy the last whole positions of reference and average group from .cpt */
2482 for (int i = 0; i < edi.sref.nr; i++)
2484 copy_rvec(EDstate->old_sref[nr_edi][i], edi.sref.x_old[i]);
2486 for (int i = 0; i < edi.sav.nr; i++)
2488 copy_rvec(EDstate->old_sav[nr_edi][i], edi.sav.x_old[i]);
2493 EDstate->nref[nr_edi] = edi.sref.nr;
2494 EDstate->nav[nr_edi] = edi.sav.nr;
2497 /* For subsequent checkpoint writing, set the edsamstate pointers to the edi arrays: */
2498 EDstate->old_sref_p[nr_edi] = edi.sref.x_old;
2499 EDstate->old_sav_p[nr_edi] = edi.sav.x_old;
2504 /* Adds 'buf' to 'str' */
2505 static void add_to_string(char** str, const char* buf)
2510 len = strlen(*str) + strlen(buf) + 1;
2516 static void add_to_string_aligned(char** str, const char* buf)
2518 char buf_aligned[STRLEN];
2520 sprintf(buf_aligned, EDcol_sfmt, buf);
2521 add_to_string(str, buf_aligned);
2525 static void nice_legend(const char*** setname,
2532 auto tmp = gmx::formatString("%c %s", EDgroupchar, value);
2533 add_to_string_aligned(LegendStr, tmp.c_str());
2534 tmp += gmx::formatString(" (%s)", unit);
2535 (*setname)[*nsets] = gmx_strdup(tmp.c_str());
2540 static void nice_legend_evec(const char*** setname,
2551 for (i = 0; i < evec->neig; i++)
2553 sprintf(tmp, "EV%dprj%s", evec->ieig[i], EDtype);
2554 nice_legend(setname, nsets, LegendStr, tmp, "nm", EDgroupChar);
2559 /* Makes a legend for the xvg output file. Call on MASTER only! */
2560 static void write_edo_legend(gmx_edsam* ed, int nED, const gmx_output_env_t* oenv)
2563 int nr_edi, nsets, n_flood, n_edsam;
2564 const char** setname;
2566 char* LegendStr = nullptr;
2569 auto edi = ed->edpar.begin();
2571 fprintf(ed->edo, "# Output will be written every %d step%s\n", edi->outfrq, edi->outfrq != 1 ? "s" : "");
2573 for (nr_edi = 1; nr_edi <= nED; nr_edi++)
2575 fprintf(ed->edo, "#\n");
2577 "# Summary of applied con/restraints for the ED group %c\n",
2578 get_EDgroupChar(nr_edi, nED));
2579 fprintf(ed->edo, "# Atoms in average structure: %d\n", edi->sav.nr);
2580 fprintf(ed->edo, "# monitor : %d vec%s\n", edi->vecs.mon.neig, edi->vecs.mon.neig != 1 ? "s" : "");
2582 "# LINFIX : %d vec%s\n",
2583 edi->vecs.linfix.neig,
2584 edi->vecs.linfix.neig != 1 ? "s" : "");
2586 "# LINACC : %d vec%s\n",
2587 edi->vecs.linacc.neig,
2588 edi->vecs.linacc.neig != 1 ? "s" : "");
2590 "# RADFIX : %d vec%s\n",
2591 edi->vecs.radfix.neig,
2592 edi->vecs.radfix.neig != 1 ? "s" : "");
2594 "# RADACC : %d vec%s\n",
2595 edi->vecs.radacc.neig,
2596 edi->vecs.radacc.neig != 1 ? "s" : "");
2598 "# RADCON : %d vec%s\n",
2599 edi->vecs.radcon.neig,
2600 edi->vecs.radcon.neig != 1 ? "s" : "");
2601 fprintf(ed->edo, "# FLOODING : %d vec%s ", edi->flood.vecs.neig, edi->flood.vecs.neig != 1 ? "s" : "");
2603 if (edi->flood.vecs.neig)
2605 /* If in any of the groups we find a flooding vector, flooding is turned on */
2606 ed->eEDtype = EssentialDynamicsType::Flooding;
2608 /* Print what flavor of flooding we will do */
2609 if (0 == edi->flood.tau) /* constant flooding strength */
2611 fprintf(ed->edo, "Efl_null = %g", edi->flood.constEfl);
2612 if (edi->flood.bHarmonic)
2614 fprintf(ed->edo, ", harmonic");
2617 else /* adaptive flooding */
2619 fprintf(ed->edo, ", adaptive");
2622 fprintf(ed->edo, "\n");
2627 /* Print a nice legend */
2629 LegendStr[0] = '\0';
2630 sprintf(buf, "# %6s", "time");
2631 add_to_string(&LegendStr, buf);
2633 /* Calculate the maximum number of columns we could end up with */
2634 edi = ed->edpar.begin();
2636 for (nr_edi = 1; nr_edi <= nED; nr_edi++)
2638 nsets += 5 + edi->vecs.mon.neig + edi->vecs.linfix.neig + edi->vecs.linacc.neig
2639 + edi->vecs.radfix.neig + edi->vecs.radacc.neig + edi->vecs.radcon.neig
2640 + 6 * edi->flood.vecs.neig;
2643 snew(setname, nsets);
2645 /* In the mdrun time step in a first function call (do_flood()) the flooding
2646 * forces are calculated and in a second function call (do_edsam()) the
2647 * ED constraints. To get a corresponding legend, we need to loop twice
2648 * over the edi groups and output first the flooding, then the ED part */
2650 /* The flooding-related legend entries, if flooding is done */
2652 if (EssentialDynamicsType::Flooding == ed->eEDtype)
2654 edi = ed->edpar.begin();
2655 for (nr_edi = 1; nr_edi <= nED; nr_edi++)
2657 /* Always write out the projection on the flooding EVs. Of course, this can also
2658 * be achieved with the monitoring option in do_edsam() (if switched on by the
2659 * user), but in that case the positions need to be communicated in do_edsam(),
2660 * which is not necessary when doing flooding only. */
2661 nice_legend(&setname, &nsets, &LegendStr, "RMSD to ref", "nm", get_EDgroupChar(nr_edi, nED));
2663 for (i = 0; i < edi->flood.vecs.neig; i++)
2665 sprintf(buf, "EV%dprjFLOOD", edi->flood.vecs.ieig[i]);
2666 nice_legend(&setname, &nsets, &LegendStr, buf, "nm", get_EDgroupChar(nr_edi, nED));
2668 /* Output the current reference projection if it changes with time;
2669 * this can happen when flooding is used as harmonic restraint */
2670 if (edi->flood.bHarmonic && edi->flood.referenceProjectionSlope[i] != 0.0)
2672 sprintf(buf, "EV%d ref.prj.", edi->flood.vecs.ieig[i]);
2673 nice_legend(&setname, &nsets, &LegendStr, buf, "nm", get_EDgroupChar(nr_edi, nED));
2676 /* For flooding we also output Efl, Vfl, deltaF, and the flooding forces */
2677 if (0 != edi->flood.tau) /* only output Efl for adaptive flooding (constant otherwise) */
2679 sprintf(buf, "EV%d-Efl", edi->flood.vecs.ieig[i]);
2680 nice_legend(&setname, &nsets, &LegendStr, buf, "kJ/mol", get_EDgroupChar(nr_edi, nED));
2683 sprintf(buf, "EV%d-Vfl", edi->flood.vecs.ieig[i]);
2684 nice_legend(&setname, &nsets, &LegendStr, buf, "kJ/mol", get_EDgroupChar(nr_edi, nED));
2686 if (0 != edi->flood.tau) /* only output deltaF for adaptive flooding (zero otherwise) */
2688 sprintf(buf, "EV%d-deltaF", edi->flood.vecs.ieig[i]);
2689 nice_legend(&setname, &nsets, &LegendStr, buf, "kJ/mol", get_EDgroupChar(nr_edi, nED));
2692 sprintf(buf, "EV%d-FLforces", edi->flood.vecs.ieig[i]);
2693 nice_legend(&setname, &nsets, &LegendStr, buf, "kJ/mol/nm", get_EDgroupChar(nr_edi, nED));
2697 } /* End of flooding-related legend entries */
2701 /* Now the ED-related entries, if essential dynamics is done */
2702 edi = ed->edpar.begin();
2703 for (nr_edi = 1; nr_edi <= nED; nr_edi++)
2705 if (bNeedDoEdsam(*edi)) /* Only print ED legend if at least one ED option is on */
2707 nice_legend(&setname, &nsets, &LegendStr, "RMSD to ref", "nm", get_EDgroupChar(nr_edi, nED));
2709 /* Essential dynamics, projections on eigenvectors */
2710 nice_legend_evec(&setname,
2714 get_EDgroupChar(nr_edi, nED),
2716 nice_legend_evec(&setname,
2720 get_EDgroupChar(nr_edi, nED),
2722 nice_legend_evec(&setname,
2726 get_EDgroupChar(nr_edi, nED),
2728 nice_legend_evec(&setname,
2732 get_EDgroupChar(nr_edi, nED),
2734 if (edi->vecs.radfix.neig)
2736 nice_legend(&setname, &nsets, &LegendStr, "RADFIX radius", "nm", get_EDgroupChar(nr_edi, nED));
2738 nice_legend_evec(&setname,
2742 get_EDgroupChar(nr_edi, nED),
2744 if (edi->vecs.radacc.neig)
2746 nice_legend(&setname, &nsets, &LegendStr, "RADACC radius", "nm", get_EDgroupChar(nr_edi, nED));
2748 nice_legend_evec(&setname,
2752 get_EDgroupChar(nr_edi, nED),
2754 if (edi->vecs.radcon.neig)
2756 nice_legend(&setname, &nsets, &LegendStr, "RADCON radius", "nm", get_EDgroupChar(nr_edi, nED));
2760 } /* end of 'pure' essential dynamics legend entries */
2761 n_edsam = nsets - n_flood;
2763 xvgr_legend(ed->edo, nsets, setname, oenv);
2768 "# Legend for %d column%s of flooding plus %d column%s of essential dynamics data:\n",
2770 1 == n_flood ? "" : "s",
2772 1 == n_edsam ? "" : "s");
2773 fprintf(ed->edo, "%s", LegendStr);
2780 /* Init routine for ED and flooding. Calls init_edi in a loop for every .edi-cycle
2781 * contained in the input file, creates a NULL terminated list of t_edpar structures */
2782 std::unique_ptr<gmx::EssentialDynamics> init_edsam(const gmx::MDLogger& mdlog,
2783 const char* ediFileName,
2784 const char* edoFileName,
2785 const gmx_mtop_t& mtop,
2786 const t_inputrec& ir,
2787 const t_commrec* cr,
2788 gmx::Constraints* constr,
2789 const t_state* globalState,
2790 ObservablesHistory* oh,
2791 const gmx_output_env_t* oenv,
2792 const gmx::StartingBehavior startingBehavior)
2795 rvec* x_pbc = nullptr; /* positions of the whole MD system with pbc removed */
2796 rvec * xfit = nullptr, *xstart = nullptr; /* dummy arrays to determine initial RMSDs */
2797 rvec fit_transvec; /* translation ... */
2798 matrix fit_rotmat; /* ... and rotation from fit to reference structure */
2799 rvec* ref_x_old = nullptr; /* helper pointer */
2804 fprintf(stderr, "ED: Initializing essential dynamics constraints.\n");
2806 if (oh->edsamHistory != nullptr && oh->edsamHistory->bFromCpt && !gmx_fexist(ediFileName))
2809 "The checkpoint file you provided is from an essential dynamics or flooding\n"
2810 "simulation. Please also set the .edi file on the command line with -ei.\n");
2816 "Activating essential dynamics via files passed to "
2817 "gmx mdrun -edi will change in future to be files passed to "
2818 "gmx grompp and the related .mdp options may change also.");
2820 /* Open input and output files, allocate space for ED data structure */
2821 auto edHandle = ed_open(mtop.natoms, oh, ediFileName, edoFileName, startingBehavior, oenv, cr);
2822 auto* ed = edHandle->getLegacyED();
2823 GMX_RELEASE_ASSERT(constr != nullptr, "Must have valid constraints object");
2824 constr->saveEdsamPointer(ed);
2826 /* Needed for initializing radacc radius in do_edsam */
2829 /* The input file is read by the master and the edi structures are
2830 * initialized here. Input is stored in ed->edpar. Then the edi
2831 * structures are transferred to the other nodes */
2834 /* Initialization for every ED/flooding group. Flooding uses one edi group per
2835 * flooding vector, Essential dynamics can be applied to more than one structure
2836 * as well, but will be done in the order given in the edi file, so
2837 * expect different results for different order of edi file concatenation! */
2838 for (auto& edi : ed->edpar)
2840 init_edi(mtop, &edi);
2841 init_flood(&edi, ed, ir.delta_t);
2845 /* The master does the work here. The other nodes get the positions
2846 * not before dd_partition_system which is called after init_edsam */
2849 edsamhistory_t* EDstate = oh->edsamHistory.get();
2851 if (!EDstate->bFromCpt)
2853 /* Remove PBC, make molecule(s) subject to ED whole. */
2854 snew(x_pbc, mtop.natoms);
2855 copy_rvecn(globalState->x.rvec_array(), x_pbc, 0, mtop.natoms);
2856 do_pbc_first_mtop(nullptr, ir.pbcType, globalState->box, &mtop, x_pbc);
2858 /* Reset pointer to first ED data set which contains the actual ED data */
2859 auto edi = ed->edpar.begin();
2860 GMX_ASSERT(!ed->edpar.empty(), "Essential dynamics parameters is undefined");
2862 /* Loop over all ED/flooding data sets (usually only one, though) */
2863 for (int nr_edi = 1; nr_edi <= EDstate->nED; nr_edi++)
2865 /* For multiple ED groups we use the output frequency that was specified
2866 * in the first set */
2869 edi->outfrq = ed->edpar.begin()->outfrq;
2872 /* Extract the initial reference and average positions. When starting
2873 * from .cpt, these have already been read into sref.x_old
2874 * in init_edsamstate() */
2875 if (!EDstate->bFromCpt)
2877 /* If this is the first run (i.e. no checkpoint present) we assume
2878 * that the starting positions give us the correct PBC representation */
2879 for (i = 0; i < edi->sref.nr; i++)
2881 copy_rvec(x_pbc[edi->sref.anrs[i]], edi->sref.x_old[i]);
2884 for (i = 0; i < edi->sav.nr; i++)
2886 copy_rvec(x_pbc[edi->sav.anrs[i]], edi->sav.x_old[i]);
2890 /* Now we have the PBC-correct start positions of the reference and
2891 average structure. We copy that over to dummy arrays on which we
2892 can apply fitting to print out the RMSD. We srenew the memory since
2893 the size of the buffers is likely different for every ED group */
2894 srenew(xfit, edi->sref.nr);
2895 srenew(xstart, edi->sav.nr);
2898 /* Reference indices are the same as average indices */
2899 ref_x_old = edi->sav.x_old;
2903 ref_x_old = edi->sref.x_old;
2905 copy_rvecn(ref_x_old, xfit, 0, edi->sref.nr);
2906 copy_rvecn(edi->sav.x_old, xstart, 0, edi->sav.nr);
2908 /* Make the fit to the REFERENCE structure, get translation and rotation */
2909 fit_to_reference(xfit, fit_transvec, fit_rotmat, &(*edi));
2911 /* Output how well we fit to the reference at the start */
2912 translate_and_rotate(xfit, edi->sref.nr, fit_transvec, fit_rotmat);
2914 "ED: Initial RMSD from reference after fit = %f nm",
2915 rmsd_from_structure(xfit, &edi->sref));
2916 if (EDstate->nED > 1)
2918 fprintf(stderr, " (ED group %c)", get_EDgroupChar(nr_edi, EDstate->nED));
2920 fprintf(stderr, "\n");
2922 /* Now apply the translation and rotation to the atoms on which ED sampling will be performed */
2923 translate_and_rotate(xstart, edi->sav.nr, fit_transvec, fit_rotmat);
2925 /* calculate initial projections */
2926 project(xstart, &(*edi));
2928 /* For the target and origin structure both a reference (fit) and an
2929 * average structure can be provided in make_edi. If both structures
2930 * are the same, make_edi only stores one of them in the .edi file.
2931 * If they differ, first the fit and then the average structure is stored
2932 * in star (or sor), thus the number of entries in star/sor is
2933 * (n_fit + n_av) with n_fit the size of the fitting group and n_av
2934 * the size of the average group. */
2936 /* process target structure, if required */
2937 if (edi->star.nr > 0)
2939 fprintf(stderr, "ED: Fitting target structure to reference structure\n");
2941 /* get translation & rotation for fit of target structure to reference structure */
2942 fit_to_reference(edi->star.x, fit_transvec, fit_rotmat, &(*edi));
2944 translate_and_rotate(edi->star.x, edi->star.nr, fit_transvec, fit_rotmat);
2945 if (edi->star.nr == edi->sav.nr)
2949 else /* edi->star.nr = edi->sref.nr + edi->sav.nr */
2951 /* The last sav.nr indices of the target structure correspond to
2952 * the average structure, which must be projected */
2953 avindex = edi->star.nr - edi->sav.nr;
2955 rad_project(*edi, &edi->star.x[avindex], &edi->vecs.radcon);
2959 rad_project(*edi, xstart, &edi->vecs.radcon);
2962 /* process structure that will serve as origin of expansion circle */
2963 if ((EssentialDynamicsType::Flooding == ed->eEDtype) && (!edi->flood.bConstForce))
2966 "ED: Setting center of flooding potential (0 = average structure)\n");
2969 if (edi->sori.nr > 0)
2971 fprintf(stderr, "ED: Fitting origin structure to reference structure\n");
2973 /* fit this structure to reference structure */
2974 fit_to_reference(edi->sori.x, fit_transvec, fit_rotmat, &(*edi));
2976 translate_and_rotate(edi->sori.x, edi->sori.nr, fit_transvec, fit_rotmat);
2977 if (edi->sori.nr == edi->sav.nr)
2981 else /* edi->sori.nr = edi->sref.nr + edi->sav.nr */
2983 /* For the projection, we need the last sav.nr indices of sori */
2984 avindex = edi->sori.nr - edi->sav.nr;
2987 rad_project(*edi, &edi->sori.x[avindex], &edi->vecs.radacc);
2988 rad_project(*edi, &edi->sori.x[avindex], &edi->vecs.radfix);
2989 if ((EssentialDynamicsType::Flooding == ed->eEDtype) && (!edi->flood.bConstForce))
2992 "ED: The ORIGIN structure will define the flooding potential "
2994 /* Set center of flooding potential to the ORIGIN structure */
2995 rad_project(*edi, &edi->sori.x[avindex], &edi->flood.vecs);
2996 /* We already know that no (moving) reference position was provided,
2997 * therefore we can overwrite refproj[0]*/
2998 copyEvecReference(&edi->flood.vecs, edi->flood.initialReferenceProjection);
3001 else /* No origin structure given */
3003 rad_project(*edi, xstart, &edi->vecs.radacc);
3004 rad_project(*edi, xstart, &edi->vecs.radfix);
3005 if ((EssentialDynamicsType::Flooding == ed->eEDtype) && (!edi->flood.bConstForce))
3007 if (edi->flood.bHarmonic)
3010 "ED: A (possibly changing) ref. projection will define the "
3011 "flooding potential center.\n");
3012 for (i = 0; i < edi->flood.vecs.neig; i++)
3014 edi->flood.vecs.refproj[i] = edi->flood.initialReferenceProjection[i];
3020 "ED: The AVERAGE structure will define the flooding potential "
3022 /* Set center of flooding potential to the center of the covariance matrix,
3023 * i.e. the average structure, i.e. zero in the projected system */
3024 for (i = 0; i < edi->flood.vecs.neig; i++)
3026 edi->flood.vecs.refproj[i] = 0.0;
3031 /* For convenience, output the center of the flooding potential for the eigenvectors */
3032 if ((EssentialDynamicsType::Flooding == ed->eEDtype) && (!edi->flood.bConstForce))
3034 for (i = 0; i < edi->flood.vecs.neig; i++)
3037 "ED: EV %d flooding potential center: %11.4e",
3038 edi->flood.vecs.ieig[i],
3039 edi->flood.vecs.refproj[i]);
3040 if (edi->flood.bHarmonic)
3042 fprintf(stdout, " (adding %11.4e/timestep)", edi->flood.referenceProjectionSlope[i]);
3044 fprintf(stdout, "\n");
3048 /* set starting projections for linsam */
3049 rad_project(*edi, xstart, &edi->vecs.linacc);
3050 rad_project(*edi, xstart, &edi->vecs.linfix);
3052 /* Prepare for the next edi data set: */
3055 /* Cleaning up on the master node: */
3056 if (!EDstate->bFromCpt)
3063 } /* end of MASTER only section */
3067 /* Broadcast the essential dynamics / flooding data to all nodes */
3068 broadcast_ed_data(cr, ed);
3072 /* In the single-CPU case, point the local atom numbers pointers to the global
3073 * one, so that we can use the same notation in serial and parallel case: */
3074 /* Loop over all ED data sets (usually only one, though) */
3075 for (auto edi = ed->edpar.begin(); edi != ed->edpar.end(); ++edi)
3077 edi->sref.anrs_loc = edi->sref.anrs;
3078 edi->sav.anrs_loc = edi->sav.anrs;
3079 edi->star.anrs_loc = edi->star.anrs;
3080 edi->sori.anrs_loc = edi->sori.anrs;
3081 /* For the same reason as above, make a dummy c_ind array: */
3082 snew(edi->sav.c_ind, edi->sav.nr);
3083 /* Initialize the array */
3084 for (i = 0; i < edi->sav.nr; i++)
3086 edi->sav.c_ind[i] = i;
3088 /* In the general case we will need a different-sized array for the reference indices: */
3091 snew(edi->sref.c_ind, edi->sref.nr);
3092 for (i = 0; i < edi->sref.nr; i++)
3094 edi->sref.c_ind[i] = i;
3097 /* Point to the very same array in case of other structures: */
3098 edi->star.c_ind = edi->sav.c_ind;
3099 edi->sori.c_ind = edi->sav.c_ind;
3100 /* In the serial case, the local number of atoms is the global one: */
3101 edi->sref.nr_loc = edi->sref.nr;
3102 edi->sav.nr_loc = edi->sav.nr;
3103 edi->star.nr_loc = edi->star.nr;
3104 edi->sori.nr_loc = edi->sori.nr;
3108 /* Allocate space for ED buffer variables */
3109 /* Again, loop over ED data sets */
3110 for (auto edi = ed->edpar.begin(); edi != ed->edpar.end(); ++edi)
3112 /* Allocate space for ED buffer variables */
3113 snew_bc(MASTER(cr), edi->buf, 1); /* MASTER has already allocated edi->buf in init_edi() */
3114 snew(edi->buf->do_edsam, 1);
3116 /* Space for collective ED buffer variables */
3118 /* Collective positions of atoms with the average indices */
3119 snew(edi->buf->do_edsam->xcoll, edi->sav.nr);
3120 snew(edi->buf->do_edsam->shifts_xcoll, edi->sav.nr); /* buffer for xcoll shifts */
3121 snew(edi->buf->do_edsam->extra_shifts_xcoll, edi->sav.nr);
3122 /* Collective positions of atoms with the reference indices */
3125 snew(edi->buf->do_edsam->xc_ref, edi->sref.nr);
3126 snew(edi->buf->do_edsam->shifts_xc_ref, edi->sref.nr); /* To store the shifts in */
3127 snew(edi->buf->do_edsam->extra_shifts_xc_ref, edi->sref.nr);
3130 /* Get memory for flooding forces */
3131 snew(edi->flood.forces_cartesian, edi->sav.nr);
3134 /* Flush the edo file so that the user can check some things
3135 * when the simulation has started */
3145 void do_edsam(const t_inputrec* ir,
3147 const t_commrec* cr,
3148 gmx::ArrayRef<gmx::RVec> coords,
3149 gmx::ArrayRef<gmx::RVec> velocities,
3153 int i, edinr, iupdate = 500;
3154 matrix rotmat; /* rotation matrix */
3155 rvec transvec; /* translation vector */
3156 rvec dv, dx, x_unsh; /* tmp vectors for velocity, distance, unshifted x coordinate */
3157 real dt_1; /* 1/dt */
3158 struct t_do_edsam* buf;
3159 real rmsdev = -1; /* RMSD from reference structure prior to applying the constraints */
3160 gmx_bool bSuppress = FALSE; /* Write .xvg output file on master? */
3163 /* Check if ED sampling has to be performed */
3164 if (ed->eEDtype == EssentialDynamicsType::None)
3169 dt_1 = 1.0 / ir->delta_t;
3171 /* Loop over all ED groups (usually one) */
3173 for (auto& edi : ed->edpar)
3176 if (bNeedDoEdsam(edi))
3179 buf = edi.buf->do_edsam;
3183 /* initialize radacc radius for slope criterion */
3184 buf->oldrad = calc_radius(edi.vecs.radacc);
3187 /* Copy the positions into buf->xc* arrays and after ED
3188 * feed back corrections to the official positions */
3190 /* Broadcast the ED positions such that every node has all of them
3191 * Every node contributes its local positions xs and stores it in
3192 * the collective buf->xcoll array. Note that for edinr > 1
3193 * xs could already have been modified by an earlier ED */
3195 communicate_group_positions(cr,
3198 buf->extra_shifts_xcoll,
3199 PAR(cr) ? buf->bUpdateShifts : TRUE,
3200 as_rvec_array(coords.data()),
3208 /* Only assembly reference positions if their indices differ from the average ones */
3211 communicate_group_positions(cr,
3214 buf->extra_shifts_xc_ref,
3215 PAR(cr) ? buf->bUpdateShifts : TRUE,
3216 as_rvec_array(coords.data()),
3225 /* If bUpdateShifts was TRUE then the shifts have just been updated in communicate_group_positions.
3226 * We do not need to update the shifts until the next NS step. Note that dd_make_local_ed_indices
3227 * set bUpdateShifts=TRUE in the parallel case. */
3228 buf->bUpdateShifts = FALSE;
3230 /* Now all nodes have all of the ED positions in edi.sav->xcoll,
3231 * as well as the indices in edi.sav.anrs */
3233 /* Fit the reference indices to the reference structure */
3236 fit_to_reference(buf->xcoll, transvec, rotmat, &edi);
3240 fit_to_reference(buf->xc_ref, transvec, rotmat, &edi);
3243 /* Now apply the translation and rotation to the ED structure */
3244 translate_and_rotate(buf->xcoll, edi.sav.nr, transvec, rotmat);
3246 /* Find out how well we fit to the reference (just for output steps) */
3247 if (do_per_step(step, edi.outfrq) && MASTER(cr))
3251 /* Indices of reference and average structures are identical,
3252 * thus we can calculate the rmsd to SREF using xcoll */
3253 rmsdev = rmsd_from_structure(buf->xcoll, &edi.sref);
3257 /* We have to translate & rotate the reference atoms first */
3258 translate_and_rotate(buf->xc_ref, edi.sref.nr, transvec, rotmat);
3259 rmsdev = rmsd_from_structure(buf->xc_ref, &edi.sref);
3263 /* update radsam references, when required */
3264 if (do_per_step(step, edi.maxedsteps) && step >= edi.presteps)
3266 project(buf->xcoll, &edi);
3267 rad_project(edi, buf->xcoll, &edi.vecs.radacc);
3268 rad_project(edi, buf->xcoll, &edi.vecs.radfix);
3269 buf->oldrad = -1.e5;
3272 /* update radacc references, when required */
3273 if (do_per_step(step, iupdate) && step >= edi.presteps)
3275 edi.vecs.radacc.radius = calc_radius(edi.vecs.radacc);
3276 if (edi.vecs.radacc.radius - buf->oldrad < edi.slope)
3278 project(buf->xcoll, &edi);
3279 rad_project(edi, buf->xcoll, &edi.vecs.radacc);
3284 buf->oldrad = edi.vecs.radacc.radius;
3288 /* apply the constraints */
3289 if (step >= edi.presteps && ed_constraints(ed->eEDtype, edi))
3291 /* ED constraints should be applied already in the first MD step
3292 * (which is step 0), therefore we pass step+1 to the routine */
3293 ed_apply_constraints(buf->xcoll, &edi, step + 1 - ir->init_step);
3296 /* write to edo, when required */
3297 if (do_per_step(step, edi.outfrq))
3299 project(buf->xcoll, &edi);
3300 if (MASTER(cr) && !bSuppress)
3302 write_edo(edi, ed->edo, rmsdev);
3306 /* Copy back the positions unless monitoring only */
3307 if (ed_constraints(ed->eEDtype, edi))
3309 /* remove fitting */
3310 rmfit(edi.sav.nr, buf->xcoll, transvec, rotmat);
3312 /* Copy the ED corrected positions into the coordinate array */
3313 /* Each node copies its local part. In the serial case, nat_loc is the
3314 * total number of ED atoms */
3315 for (i = 0; i < edi.sav.nr_loc; i++)
3317 /* Unshift local ED coordinate and store in x_unsh */
3318 ed_unshift_single_coord(
3319 box, buf->xcoll[edi.sav.c_ind[i]], buf->shifts_xcoll[edi.sav.c_ind[i]], x_unsh);
3321 /* dx is the ED correction to the positions: */
3322 rvec_sub(x_unsh, coords[edi.sav.anrs_loc[i]], dx);
3324 if (!velocities.empty())
3326 /* dv is the ED correction to the velocity: */
3327 svmul(dt_1, dx, dv);
3328 /* apply the velocity correction: */
3329 rvec_inc(velocities[edi.sav.anrs_loc[i]], dv);
3331 /* Finally apply the position correction due to ED: */
3332 copy_rvec(x_unsh, coords[edi.sav.anrs_loc[i]]);
3335 } /* END of if ( bNeedDoEdsam(edi) ) */
3337 /* Prepare for the next ED group */
3339 } /* END of loop over ED groups */