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, led by
7 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8 * and including many others, as listed in the AUTHORS file in the
9 * top-level source directory and at http://www.gromacs.org.
11 * GROMACS is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 2.1
14 * of the License, or (at your option) any later version.
16 * GROMACS is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with GROMACS; if not, see
23 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 * If you want to redistribute modifications to GROMACS, please
27 * consider that scientific software is very special. Version
28 * control is crucial - bugs must be traceable. We will be happy to
29 * consider code for inclusion in the official distribution, but
30 * derived work must not be called official GROMACS. Details are found
31 * in the README & COPYING files - if they are missing, get the
32 * official version at http://www.gromacs.org.
34 * To help us fund GROMACS development, we humbly ask that you cite
35 * the research papers on the package. Check out http://www.gromacs.org.
45 #include "gromacs/awh/awh.h"
46 #include "gromacs/fileio/enxio.h"
47 #include "gromacs/fileio/gmxfio.h"
48 #include "gromacs/fileio/xvgr.h"
49 #include "gromacs/gmxlib/network.h"
50 #include "gromacs/listed-forces/disre.h"
51 #include "gromacs/listed-forces/orires.h"
52 #include "gromacs/math/functions.h"
53 #include "gromacs/math/units.h"
54 #include "gromacs/math/vec.h"
55 #include "gromacs/mdlib/constr.h"
56 #include "gromacs/mdlib/mdebin_bar.h"
57 #include "gromacs/mdlib/mdrun.h"
58 #include "gromacs/mdtypes/energyhistory.h"
59 #include "gromacs/mdtypes/fcdata.h"
60 #include "gromacs/mdtypes/group.h"
61 #include "gromacs/mdtypes/inputrec.h"
62 #include "gromacs/mdtypes/md_enums.h"
63 #include "gromacs/mdtypes/state.h"
64 #include "gromacs/pbcutil/pbc.h"
65 #include "gromacs/pulling/pull.h"
66 #include "gromacs/topology/mtop_util.h"
67 #include "gromacs/utility/arraysize.h"
68 #include "gromacs/utility/fatalerror.h"
69 #include "gromacs/utility/smalloc.h"
71 static const char *conrmsd_nm
[] = { "Constr. rmsd", "Constr.2 rmsd" };
73 static const char *boxs_nm
[] = { "Box-X", "Box-Y", "Box-Z" };
75 static const char *tricl_boxs_nm
[] = {
76 "Box-XX", "Box-YY", "Box-ZZ",
77 "Box-YX", "Box-ZX", "Box-ZY"
80 static const char *vol_nm
[] = { "Volume" };
82 static const char *dens_nm
[] = {"Density" };
84 static const char *pv_nm
[] = {"pV" };
86 static const char *enthalpy_nm
[] = {"Enthalpy" };
88 static const char *boxvel_nm
[] = {
89 "Box-Vel-XX", "Box-Vel-YY", "Box-Vel-ZZ",
90 "Box-Vel-YX", "Box-Vel-ZX", "Box-Vel-ZY"
93 #define NBOXS asize(boxs_nm)
94 #define NTRICLBOXS asize(tricl_boxs_nm)
96 t_mdebin
*init_mdebin(ener_file_t fp_ene
,
97 const gmx_mtop_t
*mtop
,
101 const char *ener_nm
[F_NRE
];
102 static const char *vir_nm
[] = {
103 "Vir-XX", "Vir-XY", "Vir-XZ",
104 "Vir-YX", "Vir-YY", "Vir-YZ",
105 "Vir-ZX", "Vir-ZY", "Vir-ZZ"
107 static const char *sv_nm
[] = {
108 "ShakeVir-XX", "ShakeVir-XY", "ShakeVir-XZ",
109 "ShakeVir-YX", "ShakeVir-YY", "ShakeVir-YZ",
110 "ShakeVir-ZX", "ShakeVir-ZY", "ShakeVir-ZZ"
112 static const char *fv_nm
[] = {
113 "ForceVir-XX", "ForceVir-XY", "ForceVir-XZ",
114 "ForceVir-YX", "ForceVir-YY", "ForceVir-YZ",
115 "ForceVir-ZX", "ForceVir-ZY", "ForceVir-ZZ"
117 static const char *pres_nm
[] = {
118 "Pres-XX", "Pres-XY", "Pres-XZ",
119 "Pres-YX", "Pres-YY", "Pres-YZ",
120 "Pres-ZX", "Pres-ZY", "Pres-ZZ"
122 static const char *surft_nm
[] = {
125 static const char *mu_nm
[] = {
126 "Mu-X", "Mu-Y", "Mu-Z"
128 static const char *vcos_nm
[] = {
131 static const char *visc_nm
[] = {
134 static const char *baro_nm
[] = {
139 const gmx_groups_t
*groups
;
144 int i
, j
, ni
, nj
, n
, k
, kk
, ncon
, nset
;
149 if (EI_DYNAMICS(ir
->eI
))
151 md
->delta_t
= ir
->delta_t
;
158 groups
= &mtop
->groups
;
160 bBHAM
= (mtop
->ffparams
.functype
[0] == F_BHAM
);
161 b14
= (gmx_mtop_ftype_count(mtop
, F_LJ14
) > 0 ||
162 gmx_mtop_ftype_count(mtop
, F_LJC14_Q
) > 0);
164 ncon
= gmx_mtop_ftype_count(mtop
, F_CONSTR
);
165 nset
= gmx_mtop_ftype_count(mtop
, F_SETTLE
);
166 md
->bConstr
= (ncon
> 0 || nset
> 0);
167 md
->bConstrVir
= FALSE
;
170 if (ncon
> 0 && ir
->eConstrAlg
== econtLINCS
)
174 md
->bConstrVir
= (getenv("GMX_CONSTRAINTVIR") != nullptr);
181 /* Energy monitoring */
182 for (i
= 0; i
< egNR
; i
++)
184 md
->bEInd
[i
] = FALSE
;
187 for (i
= 0; i
< F_NRE
; i
++)
189 md
->bEner
[i
] = FALSE
;
192 md
->bEner
[i
] = !bBHAM
;
194 else if (i
== F_BHAM
)
196 md
->bEner
[i
] = bBHAM
;
200 md
->bEner
[i
] = ir
->bQMMM
;
202 else if (i
== F_RF_EXCL
)
204 md
->bEner
[i
] = (EEL_RF(ir
->coulombtype
) && ir
->cutoff_scheme
== ecutsGROUP
);
206 else if (i
== F_COUL_RECIP
)
208 md
->bEner
[i
] = EEL_FULL(ir
->coulombtype
);
210 else if (i
== F_LJ_RECIP
)
212 md
->bEner
[i
] = EVDW_PME(ir
->vdwtype
);
214 else if (i
== F_LJ14
)
218 else if (i
== F_COUL14
)
222 else if (i
== F_LJC14_Q
|| i
== F_LJC_PAIRS_NB
)
224 md
->bEner
[i
] = FALSE
;
226 else if ((i
== F_DVDL_COUL
&& ir
->fepvals
->separate_dvdl
[efptCOUL
]) ||
227 (i
== F_DVDL_VDW
&& ir
->fepvals
->separate_dvdl
[efptVDW
]) ||
228 (i
== F_DVDL_BONDED
&& ir
->fepvals
->separate_dvdl
[efptBONDED
]) ||
229 (i
== F_DVDL_RESTRAINT
&& ir
->fepvals
->separate_dvdl
[efptRESTRAINT
]) ||
230 (i
== F_DKDL
&& ir
->fepvals
->separate_dvdl
[efptMASS
]) ||
231 (i
== F_DVDL
&& ir
->fepvals
->separate_dvdl
[efptFEP
]))
233 md
->bEner
[i
] = (ir
->efep
!= efepNO
);
235 else if ((interaction_function
[i
].flags
& IF_VSITE
) ||
236 (i
== F_CONSTR
) || (i
== F_CONSTRNC
) || (i
== F_SETTLE
))
238 md
->bEner
[i
] = FALSE
;
240 else if ((i
== F_COUL_SR
) || (i
== F_EPOT
) || (i
== F_PRES
) || (i
== F_EQM
))
244 else if ((i
== F_GBPOL
) && ir
->implicit_solvent
== eisGBSA
)
248 else if ((i
== F_NPSOLVATION
) && ir
->implicit_solvent
== eisGBSA
&& (ir
->sa_algorithm
!= esaNO
))
252 else if ((i
== F_GB12
) || (i
== F_GB13
) || (i
== F_GB14
))
254 md
->bEner
[i
] = FALSE
;
256 else if ((i
== F_ETOT
) || (i
== F_EKIN
) || (i
== F_TEMP
))
258 md
->bEner
[i
] = EI_DYNAMICS(ir
->eI
);
260 else if (i
== F_DISPCORR
|| i
== F_PDISPCORR
)
262 md
->bEner
[i
] = (ir
->eDispCorr
!= edispcNO
);
264 else if (i
== F_DISRESVIOL
)
266 md
->bEner
[i
] = (gmx_mtop_ftype_count(mtop
, F_DISRES
) > 0);
268 else if (i
== F_ORIRESDEV
)
270 md
->bEner
[i
] = (gmx_mtop_ftype_count(mtop
, F_ORIRES
) > 0);
272 else if (i
== F_CONNBONDS
)
274 md
->bEner
[i
] = FALSE
;
276 else if (i
== F_COM_PULL
)
278 md
->bEner
[i
] = (ir
->bPull
&& pull_have_potential(ir
->pull_work
));
280 else if (i
== F_ECONSERVED
)
282 md
->bEner
[i
] = (integratorHasConservedEnergyQuantity(ir
));
286 md
->bEner
[i
] = (gmx_mtop_ftype_count(mtop
, i
) > 0);
291 for (i
= 0; i
< F_NRE
; i
++)
295 ener_nm
[md
->f_nre
] = interaction_function
[i
].longname
;
301 md
->bDiagPres
= !TRICLINIC(ir
->ref_p
);
302 md
->ref_p
= (ir
->ref_p
[XX
][XX
]+ir
->ref_p
[YY
][YY
]+ir
->ref_p
[ZZ
][ZZ
])/DIM
;
303 md
->bTricl
= TRICLINIC(ir
->compress
) || TRICLINIC(ir
->deform
);
304 md
->bDynBox
= inputrecDynamicBox(ir
);
306 md
->bNHC_trotter
= inputrecNvtTrotter(ir
);
307 md
->bPrintNHChains
= ir
->bPrintNHChains
;
308 md
->bMTTK
= (inputrecNptTrotter(ir
) || inputrecNphTrotter(ir
));
309 md
->bMu
= inputrecNeedMutot(ir
);
311 md
->ebin
= mk_ebin();
312 /* Pass NULL for unit to let get_ebin_space determine the units
313 * for interaction_function[i].longname
315 md
->ie
= get_ebin_space(md
->ebin
, md
->f_nre
, ener_nm
, nullptr);
318 /* This should be called directly after the call for md->ie,
319 * such that md->iconrmsd follows directly in the list.
321 md
->iconrmsd
= get_ebin_space(md
->ebin
, md
->nCrmsd
, conrmsd_nm
, "");
325 md
->ib
= get_ebin_space(md
->ebin
,
326 md
->bTricl
? NTRICLBOXS
: NBOXS
,
327 md
->bTricl
? tricl_boxs_nm
: boxs_nm
,
329 md
->ivol
= get_ebin_space(md
->ebin
, 1, vol_nm
, unit_volume
);
330 md
->idens
= get_ebin_space(md
->ebin
, 1, dens_nm
, unit_density_SI
);
333 md
->ipv
= get_ebin_space(md
->ebin
, 1, pv_nm
, unit_energy
);
334 md
->ienthalpy
= get_ebin_space(md
->ebin
, 1, enthalpy_nm
, unit_energy
);
339 md
->isvir
= get_ebin_space(md
->ebin
, asize(sv_nm
), sv_nm
, unit_energy
);
340 md
->ifvir
= get_ebin_space(md
->ebin
, asize(fv_nm
), fv_nm
, unit_energy
);
342 md
->ivir
= get_ebin_space(md
->ebin
, asize(vir_nm
), vir_nm
, unit_energy
);
343 md
->ipres
= get_ebin_space(md
->ebin
, asize(pres_nm
), pres_nm
, unit_pres_bar
);
344 md
->isurft
= get_ebin_space(md
->ebin
, asize(surft_nm
), surft_nm
,
346 if (md
->epc
== epcPARRINELLORAHMAN
|| md
->epc
== epcMTTK
)
348 md
->ipc
= get_ebin_space(md
->ebin
, md
->bTricl
? 6 : 3,
349 boxvel_nm
, unit_vel
);
353 md
->imu
= get_ebin_space(md
->ebin
, asize(mu_nm
), mu_nm
, unit_dipole_D
);
355 if (ir
->cos_accel
!= 0)
357 md
->ivcos
= get_ebin_space(md
->ebin
, asize(vcos_nm
), vcos_nm
, unit_vel
);
358 md
->ivisc
= get_ebin_space(md
->ebin
, asize(visc_nm
), visc_nm
,
362 /* Energy monitoring */
363 for (i
= 0; i
< egNR
; i
++)
365 md
->bEInd
[i
] = FALSE
;
367 md
->bEInd
[egCOULSR
] = TRUE
;
368 md
->bEInd
[egLJSR
] = TRUE
;
372 md
->bEInd
[egLJSR
] = FALSE
;
373 md
->bEInd
[egBHAMSR
] = TRUE
;
377 md
->bEInd
[egLJ14
] = TRUE
;
378 md
->bEInd
[egCOUL14
] = TRUE
;
381 for (i
= 0; (i
< egNR
); i
++)
389 n
= groups
->grps
[egcENER
].nr
;
391 md
->nE
= (n
*(n
+1))/2;
393 snew(md
->igrp
, md
->nE
);
398 for (k
= 0; (k
< md
->nEc
); k
++)
400 snew(gnm
[k
], STRLEN
);
402 for (i
= 0; (i
< groups
->grps
[egcENER
].nr
); i
++)
404 ni
= groups
->grps
[egcENER
].nm_ind
[i
];
405 for (j
= i
; (j
< groups
->grps
[egcENER
].nr
); j
++)
407 nj
= groups
->grps
[egcENER
].nm_ind
[j
];
408 for (k
= kk
= 0; (k
< egNR
); k
++)
412 sprintf(gnm
[kk
], "%s:%s-%s", egrp_nm
[k
],
413 *(groups
->grpname
[ni
]), *(groups
->grpname
[nj
]));
417 md
->igrp
[n
] = get_ebin_space(md
->ebin
, md
->nEc
,
418 (const char **)gnm
, unit_energy
);
422 for (k
= 0; (k
< md
->nEc
); k
++)
430 gmx_incons("Number of energy terms wrong");
434 md
->nTC
= groups
->grps
[egcTC
].nr
;
435 md
->nNHC
= ir
->opts
.nhchainlength
; /* shorthand for number of NH chains */
438 md
->nTCP
= 1; /* assume only one possible coupling system for barostat
445 if (md
->etc
== etcNOSEHOOVER
)
447 if (md
->bNHC_trotter
)
449 md
->mde_n
= 2*md
->nNHC
*md
->nTC
;
453 md
->mde_n
= 2*md
->nTC
;
455 if (md
->epc
== epcMTTK
)
457 md
->mdeb_n
= 2*md
->nNHC
*md
->nTCP
;
466 snew(md
->tmp_r
, md
->mde_n
);
467 snew(md
->tmp_v
, md
->mde_n
);
468 snew(md
->grpnms
, md
->mde_n
);
471 for (i
= 0; (i
< md
->nTC
); i
++)
473 ni
= groups
->grps
[egcTC
].nm_ind
[i
];
474 sprintf(buf
, "T-%s", *(groups
->grpname
[ni
]));
475 grpnms
[i
] = gmx_strdup(buf
);
477 md
->itemp
= get_ebin_space(md
->ebin
, md
->nTC
, (const char **)grpnms
,
480 if (md
->etc
== etcNOSEHOOVER
)
482 if (md
->bPrintNHChains
)
484 if (md
->bNHC_trotter
)
486 for (i
= 0; (i
< md
->nTC
); i
++)
488 ni
= groups
->grps
[egcTC
].nm_ind
[i
];
489 bufi
= *(groups
->grpname
[ni
]);
490 for (j
= 0; (j
< md
->nNHC
); j
++)
492 sprintf(buf
, "Xi-%d-%s", j
, bufi
);
493 grpnms
[2*(i
*md
->nNHC
+j
)] = gmx_strdup(buf
);
494 sprintf(buf
, "vXi-%d-%s", j
, bufi
);
495 grpnms
[2*(i
*md
->nNHC
+j
)+1] = gmx_strdup(buf
);
498 md
->itc
= get_ebin_space(md
->ebin
, md
->mde_n
,
499 (const char **)grpnms
, unit_invtime
);
502 for (i
= 0; (i
< md
->nTCP
); i
++)
504 bufi
= baro_nm
[0]; /* All barostat DOF's together for now. */
505 for (j
= 0; (j
< md
->nNHC
); j
++)
507 sprintf(buf
, "Xi-%d-%s", j
, bufi
);
508 grpnms
[2*(i
*md
->nNHC
+j
)] = gmx_strdup(buf
);
509 sprintf(buf
, "vXi-%d-%s", j
, bufi
);
510 grpnms
[2*(i
*md
->nNHC
+j
)+1] = gmx_strdup(buf
);
513 md
->itcb
= get_ebin_space(md
->ebin
, md
->mdeb_n
,
514 (const char **)grpnms
, unit_invtime
);
519 for (i
= 0; (i
< md
->nTC
); i
++)
521 ni
= groups
->grps
[egcTC
].nm_ind
[i
];
522 bufi
= *(groups
->grpname
[ni
]);
523 sprintf(buf
, "Xi-%s", bufi
);
524 grpnms
[2*i
] = gmx_strdup(buf
);
525 sprintf(buf
, "vXi-%s", bufi
);
526 grpnms
[2*i
+1] = gmx_strdup(buf
);
528 md
->itc
= get_ebin_space(md
->ebin
, md
->mde_n
,
529 (const char **)grpnms
, unit_invtime
);
533 else if (md
->etc
== etcBERENDSEN
|| md
->etc
== etcYES
||
534 md
->etc
== etcVRESCALE
)
536 for (i
= 0; (i
< md
->nTC
); i
++)
538 ni
= groups
->grps
[egcTC
].nm_ind
[i
];
539 sprintf(buf
, "Lamb-%s", *(groups
->grpname
[ni
]));
540 grpnms
[i
] = gmx_strdup(buf
);
542 md
->itc
= get_ebin_space(md
->ebin
, md
->mde_n
, (const char **)grpnms
, "");
548 md
->nU
= groups
->grps
[egcACC
].nr
;
551 snew(grpnms
, 3*md
->nU
);
552 for (i
= 0; (i
< md
->nU
); i
++)
554 ni
= groups
->grps
[egcACC
].nm_ind
[i
];
555 sprintf(buf
, "Ux-%s", *(groups
->grpname
[ni
]));
556 grpnms
[3*i
+XX
] = gmx_strdup(buf
);
557 sprintf(buf
, "Uy-%s", *(groups
->grpname
[ni
]));
558 grpnms
[3*i
+YY
] = gmx_strdup(buf
);
559 sprintf(buf
, "Uz-%s", *(groups
->grpname
[ni
]));
560 grpnms
[3*i
+ZZ
] = gmx_strdup(buf
);
562 md
->iu
= get_ebin_space(md
->ebin
, 3*md
->nU
, (const char **)grpnms
, unit_vel
);
568 do_enxnms(fp_ene
, &md
->ebin
->nener
, &md
->ebin
->enm
);
571 md
->print_grpnms
= nullptr;
573 /* check whether we're going to write dh histograms */
575 if (ir
->fepvals
->separate_dhdl_file
== esepdhdlfileNO
)
577 /* Currently dh histograms are only written with dynamics */
578 if (EI_DYNAMICS(ir
->eI
))
582 mde_delta_h_coll_init(md
->dhc
, ir
);
584 md
->fp_dhdl
= nullptr;
585 snew(md
->dE
, ir
->fepvals
->n_lambda
);
589 md
->fp_dhdl
= fp_dhdl
;
590 snew(md
->dE
, ir
->fepvals
->n_lambda
);
595 snew(md
->temperatures
, ir
->fepvals
->n_lambda
);
596 for (i
= 0; i
< ir
->fepvals
->n_lambda
; i
++)
598 md
->temperatures
[i
] = ir
->simtempvals
->temperatures
[i
];
604 /* print a lambda vector to a string
605 fep = the inputrec's FEP input data
606 i = the index of the lambda vector
607 get_native_lambda = whether to print the native lambda
608 get_names = whether to print the names rather than the values
609 str = the pre-allocated string buffer to print to. */
610 static void print_lambda_vector(t_lambda
*fep
, int i
,
611 gmx_bool get_native_lambda
, gmx_bool get_names
,
617 for (j
= 0; j
< efptNR
; j
++)
619 if (fep
->separate_dvdl
[j
])
624 str
[0] = 0; /* reset the string */
627 str
+= sprintf(str
, "("); /* set the opening parenthesis*/
629 for (j
= 0; j
< efptNR
; j
++)
631 if (fep
->separate_dvdl
[j
])
635 if (get_native_lambda
&& fep
->init_lambda
>= 0)
637 str
+= sprintf(str
, "%.4f", fep
->init_lambda
);
641 str
+= sprintf(str
, "%.4f", fep
->all_lambda
[j
][i
]);
646 str
+= sprintf(str
, "%s", efpt_singular_names
[j
]);
648 /* print comma for the next item */
651 str
+= sprintf(str
, ", ");
658 /* and add the closing parenthesis */
664 extern FILE *open_dhdl(const char *filename
, const t_inputrec
*ir
,
665 const gmx_output_env_t
*oenv
)
668 const char *dhdl
= "dH/d\\lambda", *deltag
= "\\DeltaH", *lambda
= "\\lambda",
669 *lambdastate
= "\\lambda state";
670 char title
[STRLEN
], label_x
[STRLEN
], label_y
[STRLEN
];
671 int i
, nps
, nsets
, nsets_de
, nsetsbegin
;
672 int n_lambda_terms
= 0;
673 t_lambda
*fep
= ir
->fepvals
; /* for simplicity */
674 t_expanded
*expand
= ir
->expandedvals
;
676 char buf
[STRLEN
], lambda_vec_str
[STRLEN
], lambda_name_str
[STRLEN
];
682 gmx_bool write_pV
= FALSE
;
684 /* count the number of different lambda terms */
685 for (i
= 0; i
< efptNR
; i
++)
687 if (fep
->separate_dvdl
[i
])
693 if (fep
->n_lambda
== 0)
695 sprintf(title
, "%s", dhdl
);
696 sprintf(label_x
, "Time (ps)");
697 sprintf(label_y
, "%s (%s %s)",
698 dhdl
, unit_energy
, "[\\lambda]\\S-1\\N");
702 sprintf(title
, "%s and %s", dhdl
, deltag
);
703 sprintf(label_x
, "Time (ps)");
704 sprintf(label_y
, "%s and %s (%s %s)",
705 dhdl
, deltag
, unit_energy
, "[\\8l\\4]\\S-1\\N");
707 fp
= gmx_fio_fopen(filename
, "w+");
708 xvgr_header(fp
, title
, label_x
, label_y
, exvggtXNY
, oenv
);
712 bufplace
= sprintf(buf
, "T = %g (K) ",
715 if ((ir
->efep
!= efepSLOWGROWTH
) && (ir
->efep
!= efepEXPANDED
))
717 if ( (fep
->init_lambda
>= 0) && (n_lambda_terms
== 1 ))
719 /* compatibility output */
720 sprintf(&(buf
[bufplace
]), "%s = %.4f", lambda
, fep
->init_lambda
);
724 print_lambda_vector(fep
, fep
->init_fep_state
, TRUE
, FALSE
,
726 print_lambda_vector(fep
, fep
->init_fep_state
, TRUE
, TRUE
,
728 sprintf(&(buf
[bufplace
]), "%s %d: %s = %s",
729 lambdastate
, fep
->init_fep_state
,
730 lambda_name_str
, lambda_vec_str
);
733 xvgr_subtitle(fp
, buf
, oenv
);
737 if (fep
->dhdl_derivatives
== edhdlderivativesYES
)
739 nsets_dhdl
= n_lambda_terms
;
741 /* count the number of delta_g states */
742 nsets_de
= fep
->lambda_stop_n
- fep
->lambda_start_n
;
744 nsets
= nsets_dhdl
+ nsets_de
; /* dhdl + fep differences */
746 if (fep
->n_lambda
> 0 && (expand
->elmcmove
> elmcmoveNO
))
748 nsets
+= 1; /*add fep state for expanded ensemble */
751 if (fep
->edHdLPrintEnergy
!= edHdLPrintEnergyNO
)
753 nsets
+= 1; /* add energy to the dhdl as well */
757 if ((ir
->epc
!= epcNO
) && (fep
->n_lambda
> 0) && (fep
->init_lambda
< 0))
759 nsetsextend
+= 1; /* for PV term, other terms possible if required for
760 the reduced potential (only needed with foreign
761 lambda, and only output when init_lambda is not
762 set in order to maintain compatibility of the
766 snew(setname
, nsetsextend
);
768 if (expand
->elmcmove
> elmcmoveNO
)
770 /* state for the fep_vals, if we have alchemical sampling */
771 sprintf(buf
, "%s", "Thermodynamic state");
772 setname
[s
] = gmx_strdup(buf
);
776 if (fep
->edHdLPrintEnergy
!= edHdLPrintEnergyNO
)
778 switch (fep
->edHdLPrintEnergy
)
780 case edHdLPrintEnergyPOTENTIAL
:
781 sprintf(buf
, "%s (%s)", "Potential Energy", unit_energy
);
783 case edHdLPrintEnergyTOTAL
:
784 case edHdLPrintEnergyYES
:
786 sprintf(buf
, "%s (%s)", "Total Energy", unit_energy
);
788 setname
[s
] = gmx_strdup(buf
);
792 if (fep
->dhdl_derivatives
== edhdlderivativesYES
)
794 for (i
= 0; i
< efptNR
; i
++)
796 if (fep
->separate_dvdl
[i
])
799 if ( (fep
->init_lambda
>= 0) && (n_lambda_terms
== 1 ))
801 /* compatibility output */
802 sprintf(buf
, "%s %s %.4f", dhdl
, lambda
, fep
->init_lambda
);
806 double lam
= fep
->init_lambda
;
807 if (fep
->init_lambda
< 0)
809 lam
= fep
->all_lambda
[i
][fep
->init_fep_state
];
811 sprintf(buf
, "%s %s = %.4f", dhdl
, efpt_singular_names
[i
],
814 setname
[s
] = gmx_strdup(buf
);
820 if (fep
->n_lambda
> 0)
822 /* g_bar has to determine the lambda values used in this simulation
823 * from this xvg legend.
826 if (expand
->elmcmove
> elmcmoveNO
)
828 nsetsbegin
= 1; /* for including the expanded ensemble */
835 if (fep
->edHdLPrintEnergy
!= edHdLPrintEnergyNO
)
839 nsetsbegin
+= nsets_dhdl
;
841 for (i
= fep
->lambda_start_n
; i
< fep
->lambda_stop_n
; i
++)
843 print_lambda_vector(fep
, i
, FALSE
, FALSE
, lambda_vec_str
);
844 if ( (fep
->init_lambda
>= 0) && (n_lambda_terms
== 1 ))
846 /* for compatible dhdl.xvg files */
847 nps
= sprintf(buf
, "%s %s %s", deltag
, lambda
, lambda_vec_str
);
851 nps
= sprintf(buf
, "%s %s to %s", deltag
, lambda
, lambda_vec_str
);
856 /* print the temperature for this state if doing simulated annealing */
857 sprintf(&buf
[nps
], "T = %g (%s)",
858 ir
->simtempvals
->temperatures
[s
-(nsetsbegin
)],
861 setname
[s
] = gmx_strdup(buf
);
866 sprintf(buf
, "pV (%s)", unit_energy
);
867 setname
[nsetsextend
-1] = gmx_strdup(buf
); /* the first entry after
871 xvgr_legend(fp
, nsetsextend
, (const char **)setname
, oenv
);
873 for (s
= 0; s
< nsetsextend
; s
++)
883 static void copy_energy(t_mdebin
*md
, real e
[], real ecpy
[])
887 for (i
= j
= 0; (i
< F_NRE
); i
++)
896 gmx_incons("Number of energy terms wrong");
900 void upd_mdebin(t_mdebin
*md
,
905 gmx_enerdata_t
*enerd
,
914 gmx_ekindata_t
*ekind
,
918 int i
, j
, k
, kk
, n
, gid
;
919 real crmsd
[2], tmp6
[6];
920 real bs
[NTRICLBOXS
], vol
, dens
, pv
, enthalpy
;
923 double store_dhdl
[efptNR
];
924 real store_energy
= 0;
927 /* Do NOT use the box in the state variable, but the separate box provided
928 * as an argument. This is because we sometimes need to write the box from
929 * the last timestep to match the trajectory frames.
931 copy_energy(md
, enerd
->term
, ecopy
);
932 add_ebin(md
->ebin
, md
->ie
, md
->f_nre
, ecopy
, bSum
);
935 crmsd
[0] = constr_rmsd(constr
);
936 add_ebin(md
->ebin
, md
->iconrmsd
, md
->nCrmsd
, crmsd
, FALSE
);
958 vol
= box
[XX
][XX
]*box
[YY
][YY
]*box
[ZZ
][ZZ
];
959 dens
= (tmass
*AMU
)/(vol
*NANO
*NANO
*NANO
);
960 add_ebin(md
->ebin
, md
->ib
, nboxs
, bs
, bSum
);
961 add_ebin(md
->ebin
, md
->ivol
, 1, &vol
, bSum
);
962 add_ebin(md
->ebin
, md
->idens
, 1, &dens
, bSum
);
966 /* This is pV (in kJ/mol). The pressure is the reference pressure,
967 not the instantaneous pressure */
968 pv
= vol
*md
->ref_p
/PRESFAC
;
970 add_ebin(md
->ebin
, md
->ipv
, 1, &pv
, bSum
);
971 enthalpy
= pv
+ enerd
->term
[F_ETOT
];
972 add_ebin(md
->ebin
, md
->ienthalpy
, 1, &enthalpy
, bSum
);
977 add_ebin(md
->ebin
, md
->isvir
, 9, svir
[0], bSum
);
978 add_ebin(md
->ebin
, md
->ifvir
, 9, fvir
[0], bSum
);
980 add_ebin(md
->ebin
, md
->ivir
, 9, vir
[0], bSum
);
981 add_ebin(md
->ebin
, md
->ipres
, 9, pres
[0], bSum
);
982 tmp
= (pres
[ZZ
][ZZ
]-(pres
[XX
][XX
]+pres
[YY
][YY
])*0.5)*box
[ZZ
][ZZ
];
983 add_ebin(md
->ebin
, md
->isurft
, 1, &tmp
, bSum
);
984 if (md
->epc
== epcPARRINELLORAHMAN
|| md
->epc
== epcMTTK
)
986 tmp6
[0] = state
->boxv
[XX
][XX
];
987 tmp6
[1] = state
->boxv
[YY
][YY
];
988 tmp6
[2] = state
->boxv
[ZZ
][ZZ
];
989 tmp6
[3] = state
->boxv
[YY
][XX
];
990 tmp6
[4] = state
->boxv
[ZZ
][XX
];
991 tmp6
[5] = state
->boxv
[ZZ
][YY
];
992 add_ebin(md
->ebin
, md
->ipc
, md
->bTricl
? 6 : 3, tmp6
, bSum
);
996 add_ebin(md
->ebin
, md
->imu
, 3, mu_tot
, bSum
);
998 if (ekind
&& ekind
->cosacc
.cos_accel
!= 0)
1000 vol
= box
[XX
][XX
]*box
[YY
][YY
]*box
[ZZ
][ZZ
];
1001 dens
= (tmass
*AMU
)/(vol
*NANO
*NANO
*NANO
);
1002 add_ebin(md
->ebin
, md
->ivcos
, 1, &(ekind
->cosacc
.vcos
), bSum
);
1003 /* 1/viscosity, unit 1/(kg m^-1 s^-1) */
1004 tmp
= 1/(ekind
->cosacc
.cos_accel
/(ekind
->cosacc
.vcos
*PICO
)
1005 *dens
*gmx::square(box
[ZZ
][ZZ
]*NANO
/(2*M_PI
)));
1006 add_ebin(md
->ebin
, md
->ivisc
, 1, &tmp
, bSum
);
1011 for (i
= 0; (i
< md
->nEg
); i
++)
1013 for (j
= i
; (j
< md
->nEg
); j
++)
1015 gid
= GID(i
, j
, md
->nEg
);
1016 for (k
= kk
= 0; (k
< egNR
); k
++)
1020 eee
[kk
++] = enerd
->grpp
.ener
[k
][gid
];
1023 add_ebin(md
->ebin
, md
->igrp
[n
], md
->nEc
, eee
, bSum
);
1031 for (i
= 0; (i
< md
->nTC
); i
++)
1033 md
->tmp_r
[i
] = ekind
->tcstat
[i
].T
;
1035 add_ebin(md
->ebin
, md
->itemp
, md
->nTC
, md
->tmp_r
, bSum
);
1037 if (md
->etc
== etcNOSEHOOVER
)
1039 /* whether to print Nose-Hoover chains: */
1040 if (md
->bPrintNHChains
)
1042 if (md
->bNHC_trotter
)
1044 for (i
= 0; (i
< md
->nTC
); i
++)
1046 for (j
= 0; j
< md
->nNHC
; j
++)
1049 md
->tmp_r
[2*k
] = state
->nosehoover_xi
[k
];
1050 md
->tmp_r
[2*k
+1] = state
->nosehoover_vxi
[k
];
1053 add_ebin(md
->ebin
, md
->itc
, md
->mde_n
, md
->tmp_r
, bSum
);
1057 for (i
= 0; (i
< md
->nTCP
); i
++)
1059 for (j
= 0; j
< md
->nNHC
; j
++)
1062 md
->tmp_r
[2*k
] = state
->nhpres_xi
[k
];
1063 md
->tmp_r
[2*k
+1] = state
->nhpres_vxi
[k
];
1066 add_ebin(md
->ebin
, md
->itcb
, md
->mdeb_n
, md
->tmp_r
, bSum
);
1071 for (i
= 0; (i
< md
->nTC
); i
++)
1073 md
->tmp_r
[2*i
] = state
->nosehoover_xi
[i
];
1074 md
->tmp_r
[2*i
+1] = state
->nosehoover_vxi
[i
];
1076 add_ebin(md
->ebin
, md
->itc
, md
->mde_n
, md
->tmp_r
, bSum
);
1080 else if (md
->etc
== etcBERENDSEN
|| md
->etc
== etcYES
||
1081 md
->etc
== etcVRESCALE
)
1083 for (i
= 0; (i
< md
->nTC
); i
++)
1085 md
->tmp_r
[i
] = ekind
->tcstat
[i
].lambda
;
1087 add_ebin(md
->ebin
, md
->itc
, md
->nTC
, md
->tmp_r
, bSum
);
1091 if (ekind
&& md
->nU
> 1)
1093 for (i
= 0; (i
< md
->nU
); i
++)
1095 copy_rvec(ekind
->grpstat
[i
].u
, md
->tmp_v
[i
]);
1097 add_ebin(md
->ebin
, md
->iu
, 3*md
->nU
, md
->tmp_v
[0], bSum
);
1100 ebin_increase_count(md
->ebin
, bSum
);
1102 /* BAR + thermodynamic integration values */
1103 if ((md
->fp_dhdl
|| md
->dhc
) && bDoDHDL
)
1105 for (i
= 0; i
< enerd
->n_lambda
-1; i
++)
1107 /* zero for simulated tempering */
1108 md
->dE
[i
] = enerd
->enerpart_lambda
[i
+1]-enerd
->enerpart_lambda
[0];
1109 if (md
->temperatures
!= nullptr)
1111 /* MRS: is this right, given the way we have defined the exchange probabilities? */
1112 /* is this even useful to have at all? */
1113 md
->dE
[i
] += (md
->temperatures
[i
]/
1114 md
->temperatures
[state
->fep_state
]-1.0)*
1115 enerd
->term
[F_EKIN
];
1121 fprintf(md
->fp_dhdl
, "%.4f", time
);
1122 /* the current free energy state */
1124 /* print the current state if we are doing expanded ensemble */
1125 if (expand
->elmcmove
> elmcmoveNO
)
1127 fprintf(md
->fp_dhdl
, " %4d", state
->fep_state
);
1129 /* total energy (for if the temperature changes */
1131 if (fep
->edHdLPrintEnergy
!= edHdLPrintEnergyNO
)
1133 switch (fep
->edHdLPrintEnergy
)
1135 case edHdLPrintEnergyPOTENTIAL
:
1136 store_energy
= enerd
->term
[F_EPOT
];
1138 case edHdLPrintEnergyTOTAL
:
1139 case edHdLPrintEnergyYES
:
1141 store_energy
= enerd
->term
[F_ETOT
];
1143 fprintf(md
->fp_dhdl
, " %#.8g", store_energy
);
1146 if (fep
->dhdl_derivatives
== edhdlderivativesYES
)
1148 for (i
= 0; i
< efptNR
; i
++)
1150 if (fep
->separate_dvdl
[i
])
1152 /* assumes F_DVDL is first */
1153 fprintf(md
->fp_dhdl
, " %#.8g", enerd
->term
[F_DVDL
+i
]);
1157 for (i
= fep
->lambda_start_n
; i
< fep
->lambda_stop_n
; i
++)
1159 fprintf(md
->fp_dhdl
, " %#.8g", md
->dE
[i
]);
1163 (md
->epc
!= epcNO
) &&
1164 (enerd
->n_lambda
> 0) &&
1165 (fep
->init_lambda
< 0))
1167 fprintf(md
->fp_dhdl
, " %#.8g", pv
); /* PV term only needed when
1168 there are alternate state
1169 lambda and we're not in
1170 compatibility mode */
1172 fprintf(md
->fp_dhdl
, "\n");
1173 /* and the binary free energy output */
1175 if (md
->dhc
&& bDoDHDL
)
1178 for (i
= 0; i
< efptNR
; i
++)
1180 if (fep
->separate_dvdl
[i
])
1182 /* assumes F_DVDL is first */
1183 store_dhdl
[idhdl
] = enerd
->term
[F_DVDL
+i
];
1187 store_energy
= enerd
->term
[F_ETOT
];
1188 /* store_dh is dE */
1189 mde_delta_h_coll_add_dh(md
->dhc
,
1190 (double)state
->fep_state
,
1194 md
->dE
+ fep
->lambda_start_n
,
1201 void upd_mdebin_step(t_mdebin
*md
)
1203 ebin_increase_count(md
->ebin
, FALSE
);
1206 static void npr(FILE *log
, int n
, char c
)
1208 for (; (n
> 0); n
--)
1210 fprintf(log
, "%c", c
);
1214 static void pprint(FILE *log
, const char *s
, t_mdebin
*md
)
1218 char buf1
[22], buf2
[22];
1221 fprintf(log
, "\t<====== ");
1222 npr(log
, slen
, CHAR
);
1223 fprintf(log
, " ==>\n");
1224 fprintf(log
, "\t<==== %s ====>\n", s
);
1225 fprintf(log
, "\t<== ");
1226 npr(log
, slen
, CHAR
);
1227 fprintf(log
, " ======>\n\n");
1229 fprintf(log
, "\tStatistics over %s steps using %s frames\n",
1230 gmx_step_str(md
->ebin
->nsteps_sim
, buf1
),
1231 gmx_step_str(md
->ebin
->nsum_sim
, buf2
));
1235 void print_ebin_header(FILE *log
, gmx_int64_t steps
, double time
)
1239 fprintf(log
, " %12s %12s\n"
1241 "Step", "Time", gmx_step_str(steps
, buf
), time
);
1244 void print_ebin(ener_file_t fp_ene
, gmx_bool bEne
, gmx_bool bDR
, gmx_bool bOR
,
1246 gmx_int64_t step
, double time
,
1248 t_mdebin
*md
, t_fcdata
*fcd
,
1249 gmx_groups_t
*groups
, t_grpopts
*opts
,
1252 /*static char **grpnms=NULL;*/
1254 int i
, j
, n
, ni
, nj
, b
;
1256 real
*disre_rm3tav
, *disre_rt
;
1258 /* these are for the old-style blocks (1 subblock, only reals), because
1259 there can be only one per ID for these */
1272 fr
.nsteps
= md
->ebin
->nsteps
;
1273 fr
.dt
= md
->delta_t
;
1274 fr
.nsum
= md
->ebin
->nsum
;
1275 fr
.nre
= (bEne
) ? md
->ebin
->nener
: 0;
1276 fr
.ener
= md
->ebin
->e
;
1277 ndisre
= bDR
? fcd
->disres
.npair
: 0;
1278 disre_rm3tav
= fcd
->disres
.rm3tav
;
1279 disre_rt
= fcd
->disres
.rt
;
1280 /* Optional additional old-style (real-only) blocks. */
1281 for (i
= 0; i
< enxNR
; i
++)
1285 if (fcd
->orires
.nr
> 0 && bOR
)
1287 diagonalize_orires_tensors(&(fcd
->orires
));
1288 nr
[enxOR
] = fcd
->orires
.nr
;
1289 block
[enxOR
] = fcd
->orires
.otav
;
1291 nr
[enxORI
] = (fcd
->orires
.oinsl
!= fcd
->orires
.otav
) ?
1293 block
[enxORI
] = fcd
->orires
.oinsl
;
1294 id
[enxORI
] = enxORI
;
1295 nr
[enxORT
] = fcd
->orires
.nex
*12;
1296 block
[enxORT
] = fcd
->orires
.eig
;
1297 id
[enxORT
] = enxORT
;
1300 /* whether we are going to wrte anything out: */
1301 if (fr
.nre
|| ndisre
|| nr
[enxOR
] || nr
[enxORI
])
1304 /* the old-style blocks go first */
1306 for (i
= 0; i
< enxNR
; i
++)
1313 add_blocks_enxframe(&fr
, fr
.nblock
);
1314 for (b
= 0; b
< fr
.nblock
; b
++)
1316 add_subblocks_enxblock(&(fr
.block
[b
]), 1);
1317 fr
.block
[b
].id
= id
[b
];
1318 fr
.block
[b
].sub
[0].nr
= nr
[b
];
1320 fr
.block
[b
].sub
[0].type
= xdr_datatype_float
;
1321 fr
.block
[b
].sub
[0].fval
= block
[b
];
1323 fr
.block
[b
].sub
[0].type
= xdr_datatype_double
;
1324 fr
.block
[b
].sub
[0].dval
= block
[b
];
1328 /* check for disre block & fill it. */
1333 add_blocks_enxframe(&fr
, fr
.nblock
);
1335 add_subblocks_enxblock(&(fr
.block
[db
]), 2);
1336 fr
.block
[db
].id
= enxDISRE
;
1337 fr
.block
[db
].sub
[0].nr
= ndisre
;
1338 fr
.block
[db
].sub
[1].nr
= ndisre
;
1340 fr
.block
[db
].sub
[0].type
= xdr_datatype_float
;
1341 fr
.block
[db
].sub
[1].type
= xdr_datatype_float
;
1342 fr
.block
[db
].sub
[0].fval
= disre_rt
;
1343 fr
.block
[db
].sub
[1].fval
= disre_rm3tav
;
1345 fr
.block
[db
].sub
[0].type
= xdr_datatype_double
;
1346 fr
.block
[db
].sub
[1].type
= xdr_datatype_double
;
1347 fr
.block
[db
].sub
[0].dval
= disre_rt
;
1348 fr
.block
[db
].sub
[1].dval
= disre_rm3tav
;
1351 /* here we can put new-style blocks */
1353 /* Free energy perturbation blocks */
1356 mde_delta_h_coll_handle_block(md
->dhc
, &fr
, fr
.nblock
);
1359 /* we can now free & reset the data in the blocks */
1362 mde_delta_h_coll_reset(md
->dhc
);
1365 /* AWH bias blocks. */
1366 if (awh
!= nullptr) // TODO: add boolean in t_mdebin. See in mdebin.h.
1368 awh
->writeToEnergyFrame(step
, &fr
);
1371 /* do the actual I/O */
1372 do_enx(fp_ene
, &fr
);
1375 /* We have stored the sums, so reset the sum history */
1376 reset_ebin_sums(md
->ebin
);
1384 pprint(log
, "A V E R A G E S", md
);
1390 pprint(log
, "R M S - F L U C T U A T I O N S", md
);
1394 gmx_fatal(FARGS
, "Invalid print mode (%d)", mode
);
1399 for (i
= 0; i
< opts
->ngtc
; i
++)
1401 if (opts
->annealing
[i
] != eannNO
)
1403 fprintf(log
, "Current ref_t for group %s: %8.1f\n",
1404 *(groups
->grpname
[groups
->grps
[egcTC
].nm_ind
[i
]]),
1408 if (mode
== eprNORMAL
&& fcd
->orires
.nr
> 0)
1410 print_orires_log(log
, &(fcd
->orires
));
1412 fprintf(log
, " Energies (%s)\n", unit_energy
);
1413 pr_ebin(log
, md
->ebin
, md
->ie
, md
->f_nre
+md
->nCrmsd
, 5, mode
, TRUE
);
1416 if (mode
== eprAVER
)
1420 pr_ebin(log
, md
->ebin
, md
->ib
, md
->bTricl
? NTRICLBOXS
: NBOXS
, 5,
1426 fprintf(log
, " Constraint Virial (%s)\n", unit_energy
);
1427 pr_ebin(log
, md
->ebin
, md
->isvir
, 9, 3, mode
, FALSE
);
1429 fprintf(log
, " Force Virial (%s)\n", unit_energy
);
1430 pr_ebin(log
, md
->ebin
, md
->ifvir
, 9, 3, mode
, FALSE
);
1433 fprintf(log
, " Total Virial (%s)\n", unit_energy
);
1434 pr_ebin(log
, md
->ebin
, md
->ivir
, 9, 3, mode
, FALSE
);
1436 fprintf(log
, " Pressure (%s)\n", unit_pres_bar
);
1437 pr_ebin(log
, md
->ebin
, md
->ipres
, 9, 3, mode
, FALSE
);
1441 fprintf(log
, " Total Dipole (%s)\n", unit_dipole_D
);
1442 pr_ebin(log
, md
->ebin
, md
->imu
, 3, 3, mode
, FALSE
);
1448 if (md
->print_grpnms
== nullptr)
1450 snew(md
->print_grpnms
, md
->nE
);
1452 for (i
= 0; (i
< md
->nEg
); i
++)
1454 ni
= groups
->grps
[egcENER
].nm_ind
[i
];
1455 for (j
= i
; (j
< md
->nEg
); j
++)
1457 nj
= groups
->grps
[egcENER
].nm_ind
[j
];
1458 sprintf(buf
, "%s-%s", *(groups
->grpname
[ni
]),
1459 *(groups
->grpname
[nj
]));
1460 md
->print_grpnms
[n
++] = gmx_strdup(buf
);
1464 sprintf(buf
, "Epot (%s)", unit_energy
);
1465 fprintf(log
, "%15s ", buf
);
1466 for (i
= 0; (i
< egNR
); i
++)
1470 fprintf(log
, "%12s ", egrp_nm
[i
]);
1474 for (i
= 0; (i
< md
->nE
); i
++)
1476 fprintf(log
, "%15s", md
->print_grpnms
[i
]);
1477 pr_ebin(log
, md
->ebin
, md
->igrp
[i
], md
->nEc
, md
->nEc
, mode
,
1484 pr_ebin(log
, md
->ebin
, md
->itemp
, md
->nTC
, 4, mode
, TRUE
);
1489 fprintf(log
, "%15s %12s %12s %12s\n",
1490 "Group", "Ux", "Uy", "Uz");
1491 for (i
= 0; (i
< md
->nU
); i
++)
1493 ni
= groups
->grps
[egcACC
].nm_ind
[i
];
1494 fprintf(log
, "%15s", *groups
->grpname
[ni
]);
1495 pr_ebin(log
, md
->ebin
, md
->iu
+3*i
, 3, 3, mode
, FALSE
);
1504 void update_energyhistory(energyhistory_t
* enerhist
, const t_mdebin
* mdebin
)
1506 const t_ebin
* const ebin
= mdebin
->ebin
;
1508 enerhist
->nsteps
= ebin
->nsteps
;
1509 enerhist
->nsum
= ebin
->nsum
;
1510 enerhist
->nsteps_sim
= ebin
->nsteps_sim
;
1511 enerhist
->nsum_sim
= ebin
->nsum_sim
;
1515 /* This will only actually resize the first time */
1516 enerhist
->ener_ave
.resize(ebin
->nener
);
1517 enerhist
->ener_sum
.resize(ebin
->nener
);
1519 for (int i
= 0; i
< ebin
->nener
; i
++)
1521 enerhist
->ener_ave
[i
] = ebin
->e
[i
].eav
;
1522 enerhist
->ener_sum
[i
] = ebin
->e
[i
].esum
;
1526 if (ebin
->nsum_sim
> 0)
1528 /* This will only actually resize the first time */
1529 enerhist
->ener_sum_sim
.resize(ebin
->nener
);
1531 for (int i
= 0; i
< ebin
->nener
; i
++)
1533 enerhist
->ener_sum_sim
[i
] = ebin
->e_sim
[i
].esum
;
1538 mde_delta_h_coll_update_energyhistory(mdebin
->dhc
, enerhist
);
1542 void restore_energyhistory_from_state(t_mdebin
* mdebin
,
1543 const energyhistory_t
* enerhist
)
1545 unsigned int nener
= static_cast<unsigned int>(mdebin
->ebin
->nener
);
1547 if ((enerhist
->nsum
> 0 && nener
!= enerhist
->ener_sum
.size()) ||
1548 (enerhist
->nsum_sim
> 0 && nener
!= enerhist
->ener_sum_sim
.size()))
1550 gmx_fatal(FARGS
, "Mismatch between number of energies in run input (%d) and checkpoint file (%u or %u).",
1551 nener
, enerhist
->ener_sum
.size(), enerhist
->ener_sum_sim
.size());
1554 mdebin
->ebin
->nsteps
= enerhist
->nsteps
;
1555 mdebin
->ebin
->nsum
= enerhist
->nsum
;
1556 mdebin
->ebin
->nsteps_sim
= enerhist
->nsteps_sim
;
1557 mdebin
->ebin
->nsum_sim
= enerhist
->nsum_sim
;
1559 for (int i
= 0; i
< mdebin
->ebin
->nener
; i
++)
1561 mdebin
->ebin
->e
[i
].eav
=
1562 (enerhist
->nsum
> 0 ? enerhist
->ener_ave
[i
] : 0);
1563 mdebin
->ebin
->e
[i
].esum
=
1564 (enerhist
->nsum
> 0 ? enerhist
->ener_sum
[i
] : 0);
1565 mdebin
->ebin
->e_sim
[i
].esum
=
1566 (enerhist
->nsum_sim
> 0 ? enerhist
->ener_sum_sim
[i
] : 0);
1570 mde_delta_h_coll_restore_energyhistory(mdebin
->dhc
, enerhist
->deltaHForeignLambdas
.get());