} t_edpar;
-typedef struct gmx_edsam
+struct gmx_edsam
{
- int eEDtype; /* Type of ED: see enums above */
- FILE *edo; /* output file pointer */
- t_edpar *edpar;
- gmx_bool bFirst;
-} t_gmx_edsam;
-
+ ~gmx_edsam();
+ int eEDtype = eEDnone; /* Type of ED: see enums above */
+ FILE *edo = nullptr; /* output file pointer */
+ t_edpar *edpar = nullptr;
+ gmx_bool bFirst = false;
+};
+gmx_edsam::~gmx_edsam()
+{
+ if (edo)
+ {
+ /* edo is opened sometimes with xvgropen, sometimes with
+ * gmx_fio_fopen, so we use the least common denominator for
+ * closing. */
+ gmx_fio_fclose(edo);
+ }
+}
struct t_do_edsam
{
struct t_do_radcon * do_radcon;
};
+namespace gmx
+{
+class EssentialDynamics::Impl
+{
+ public:
+ // TODO: move all fields from gmx_edsam here and remove gmx_edsam
+ gmx_edsam essentialDynamics_;
+};
+EssentialDynamics::EssentialDynamics() : impl_(new Impl)
+{
+}
+EssentialDynamics::~EssentialDynamics() = default;
+
+gmx_edsam *EssentialDynamics::getLegacyED()
+{
+ return &impl_->essentialDynamics_;
+}
+} // namespace gmx
/* Function declarations */
static void fit_to_reference(rvec *xcoll, rvec transvec, matrix rotmat, t_edpar *edi);
static void translate_and_rotate(rvec *x, int nat, rvec transvec, matrix rotmat);
static real rmsd_from_structure(rvec *x, struct gmx_edx *s);
static int read_edi_file(const char *fn, t_edpar *edi, int nr_mdatoms);
-static void crosscheck_edi_file_vs_checkpoint(gmx_edsam_t ed, edsamhistory_t *EDstate);
-static void init_edsamstate(gmx_edsam_t ed, edsamhistory_t *EDstate);
-static void write_edo_legend(gmx_edsam_t ed, int nED, const gmx_output_env_t *oenv);
+static void crosscheck_edi_file_vs_checkpoint(const gmx_edsam &ed, edsamhistory_t *EDstate);
+static void init_edsamstate(gmx_edsam * ed, edsamhistory_t *EDstate);
+static void write_edo_legend(gmx_edsam * ed, int nED, const gmx_output_env_t *oenv);
/* End function declarations */
/* Define formats for the column width in the output file */
/* Called by init_edi, configure some flooding related variables and structures,
* print headers to output files */
-static void init_flood(t_edpar *edi, gmx_edsam_t ed, real dt)
+static void init_flood(t_edpar *edi, gmx_edsam * ed, real dt)
{
int i;
* with the essential dynamics data found in the checkpoint file (if present).
* gmx make_edi can be used to create an .edi input file.
*/
-static gmx_edsam_t ed_open(
+static std::unique_ptr<gmx::EssentialDynamics> ed_open(
int natoms,
ObservablesHistory *oh,
const char *ediFileName,
const gmx_output_env_t *oenv,
const t_commrec *cr)
{
- gmx_edsam_t ed;
+ auto edHandle = gmx::compat::make_unique<gmx::EssentialDynamics>();
+ auto ed = edHandle->getLegacyED();
int nED;
- /* Allocate space for the ED data structure */
- snew(ed, 1);
-
/* We want to perform ED (this switch might later be upgraded to eEDflood) */
ed->eEDtype = eEDedsam;
/* Make sure the checkpoint was produced in a run using this .edi file */
if (EDstate->bFromCpt)
{
- crosscheck_edi_file_vs_checkpoint(ed, EDstate);
+ crosscheck_edi_file_vs_checkpoint(*ed, EDstate);
}
else
{
write_edo_legend(ed, EDstate->nED, oenv);
}
}
- return ed;
+ return edHandle;
}
/* Broadcasts the ED / flooding data to other nodes
* and allocates memory where needed */
-static void broadcast_ed_data(const t_commrec *cr, gmx_edsam_t ed, int numedis)
+static void broadcast_ed_data(const t_commrec *cr, gmx_edsam * ed, int numedis)
{
int nr;
t_edpar *edi;
/* Call on MASTER only. Check whether the essential dynamics / flooding
* groups of the checkpoint file are consistent with the provided .edi file. */
-static void crosscheck_edi_file_vs_checkpoint(gmx_edsam_t ed, edsamhistory_t *EDstate)
+static void crosscheck_edi_file_vs_checkpoint(const gmx_edsam &ed, edsamhistory_t *EDstate)
{
t_edpar *edi = nullptr; /* points to a single edi data set */
int edinum;
"from without a checkpoint.\n");
}
- edi = ed->edpar;
+ edi = ed.edpar;
edinum = 0;
while (edi != nullptr)
{
* c) in any case, for subsequent checkpoint writing, we set the pointers in
* edsamstate to the x_old arrays, which contain the correct PBC representation of
* all ED structures at the last time step. */
-static void init_edsamstate(gmx_edsam_t ed, edsamhistory_t *EDstate)
+static void init_edsamstate(gmx_edsam * ed, edsamhistory_t *EDstate)
{
int i, nr_edi;
t_edpar *edi;
/* Makes a legend for the xvg output file. Call on MASTER only! */
-static void write_edo_legend(gmx_edsam_t ed, int nED, const gmx_output_env_t *oenv)
+static void write_edo_legend(gmx_edsam * ed, int nED, const gmx_output_env_t *oenv)
{
t_edpar *edi = nullptr;
int i;
/* Init routine for ED and flooding. Calls init_edi in a loop for every .edi-cycle
* contained in the input file, creates a NULL terminated list of t_edpar structures */
-gmx_edsam_t init_edsam(
+std::unique_ptr<gmx::EssentialDynamics> init_edsam(
const char *ediFileName,
const char *edoFileName,
const gmx_mtop_t *mtop,
}
/* Open input and output files, allocate space for ED data structure */
- gmx_edsam_t ed = ed_open(mtop->natoms, oh, ediFileName, edoFileName, bAppend, oenv, cr);
+ auto edHandle = ed_open(mtop->natoms, oh, ediFileName, edoFileName, bAppend, oenv, cr);
+ auto ed = edHandle->getLegacyED();
GMX_RELEASE_ASSERT(constr != nullptr, "Must have valid constraints object");
constr->saveEdsamPointer(ed);
fflush(ed->edo);
}
- return ed;
+ return edHandle;
}
rvec xs[],
rvec v[],
matrix box,
- gmx_edsam_t ed)
+ gmx_edsam *ed)
{
int i, edinr, iupdate = 500;
matrix rotmat; /* rotation matrix */
ed->bFirst = FALSE;
}
-
-void done_ed(gmx_edsam_t *ed)
-{
- if (*ed)
- {
- /* ed->edo is opened sometimes with xvgropen, sometimes with
- * gmx_fio_fopen, so we use the least common denominator for
- * closing. */
- gmx_fio_fclose((*ed)->edo);
- }
-
- /* TODO deallocate ed and set pointer to NULL */
-}
#ifndef GMX_ESSENTIALDYNAMICS_EDSAM_H
#define GMX_ESSENTIALDYNAMICS_EDSAM_H
+#include <memory>
+
#include "gromacs/math/vectypes.h"
#include "gromacs/utility/basedefinitions.h"
-
+#include "gromacs/utility/classhelpers.h"
/*! \brief Abstract type for essential dynamics
*
* The main type is defined only in edsam.cpp
*/
-typedef struct gmx_edsam *gmx_edsam_t;
-
+struct gmx_edsam;
struct gmx_domdec_t;
struct gmx_mtop_t;
struct gmx_output_env_t;
namespace gmx
{
class Constraints;
-}
+class EssentialDynamics
+{
+ public:
+ EssentialDynamics();
+ ~EssentialDynamics();
+
+ /*! \brief Getter for working data
+ *
+ * This is needed while the module is still under
+ * construction. */
+ gmx_edsam *getLegacyED();
+ private:
+ class Impl;
+
+ PrivateImplPointer<Impl> impl_;
+};
+} // namespace gmx
/*! \brief Applies essential dynamics constrains as defined in the .edi input file.
*
*
* \returns A pointer to the ED data structure.
*/
-gmx_edsam_t init_edsam(
+std::unique_ptr<gmx::EssentialDynamics> init_edsam(
const char *ediFileName,
const char *edoFileName,
const gmx_mtop_t *mtop,
* \param dd Domain decomposition data.
* \param ed Essential dynamics and flooding data.
*/
-void dd_make_local_ed_indices(gmx_domdec_t *dd, gmx_edsam_t ed);
+void dd_make_local_ed_indices(gmx_domdec_t *dd, gmx_edsam * ed);
/*! \brief Evaluate the flooding potential(s) and forces as requested in the .edi input file.
int64_t step,
gmx_bool bNS);
-/*! \brief Clean up
- *
- * \param ed The essential dynamics data
- */
-void done_ed(gmx_edsam_t *ed);
-
#endif
}
groups = &top_global->groups;
- gmx_edsam *ed = nullptr;
+ std::unique_ptr<EssentialDynamics> ed = nullptr;
if (opt2bSet("-ei", nfile, fnm) || observablesHistory->edsamHistory != nullptr)
{
/* Initialize essential dynamics sampling */
state->box, state->x, &state->hist,
f, force_vir, mdatoms, enerd, fcd,
state->lambda, graph,
- fr, vsite, mu_tot, t, ed,
+ fr, vsite, mu_tot, t, ed ? ed->getLegacyED() : nullptr,
(bNS ? GMX_FORCE_NS : 0) | force_flags,
ddOpenBalanceRegion, ddCloseBalanceRegion);
}
finish_swapcoords(ir->swap);
}
- /* Do essential dynamics cleanup if needed. Close .edo file */
- done_ed(&ed);
-
/* IMD cleanup, if bIMD is TRUE. */
IMD_finalize(ir->bIMD, ir->imd);