#include "gromacs/utility/basedefinitions.h"
#include "gromacs/utility/real.h"
-struct gmx_ekindata_t;
+class gmx_ekindata_t;
struct gmx_enerdata_t;
struct t_commrec;
struct t_extmass;
class energyhistory_t;
struct ener_file;
-struct gmx_ekindata_t;
+class gmx_ekindata_t;
struct gmx_enerdata_t;
struct SimulationGroups;
struct gmx_mtop_t;
#include "gromacs/mdtypes/md_enums.h"
#include "gromacs/timing/wallcycle.h"
-struct gmx_ekindata_t;
+class gmx_ekindata_t;
struct gmx_enerdata_t;
struct gmx_global_stat;
struct gmx_signalling_t;
#include "gromacs/math/vectypes.h"
-struct gmx_ekindata_t;
+class gmx_ekindata_t;
struct gmx_enerdata_t;
struct t_vcm;
struct t_inputrec;
*/
class EnergyOutputTest : public ::testing::TestWithParam<EnergyOutputTestParameters>
{
+ int numTempCouplingGroups_ = 3;
+ real cosAccel_ = 1.0;
+
public:
//! File manager
TestFileManager fileManager_;
TestReferenceChecker checker_;
EnergyOutputTest() :
+ ekindata_(numTempCouplingGroups_, cosAccel_, 1),
logFilename_(fileManager_.getTemporaryFilePath(".log")),
edrFilename_(fileManager_.getTemporaryFilePath(".edr")),
log_(std::fopen(logFilename_.c_str(), "w")),
mtop_.groups.groupNames.emplace_back(&handle);
}
- mtop_.groups.groups[SimulationAtomGroupType::EnergyOutput].resize(3);
+ mtop_.groups.groups[SimulationAtomGroupType::EnergyOutput].resize(numTempCouplingGroups_);
mtop_.groups.groups[SimulationAtomGroupType::EnergyOutput][0] = 0;
mtop_.groups.groups[SimulationAtomGroupType::EnergyOutput][1] = 1;
mtop_.groups.groups[SimulationAtomGroupType::EnergyOutput][2] = 2;
- mtop_.groups.groups[SimulationAtomGroupType::TemperatureCoupling].resize(3);
+ mtop_.groups.groups[SimulationAtomGroupType::TemperatureCoupling].resize(numTempCouplingGroups_);
mtop_.groups.groups[SimulationAtomGroupType::TemperatureCoupling][0] = 0;
mtop_.groups.groups[SimulationAtomGroupType::TemperatureCoupling][1] = 1;
mtop_.groups.groups[SimulationAtomGroupType::TemperatureCoupling][2] = 2;
ekindata_.tcstat.resize(mtop_.groups.groups[SimulationAtomGroupType::TemperatureCoupling].size());
// This is needed so that the ebin space will be allocated
- inputrec_.cos_accel = 1.0;
- // This is to keep the destructor happy (otherwise sfree() segfaults)
- ekindata_.nthreads = 0;
- snew(ekindata_.ekin_work_alloc, 1);
- snew(ekindata_.ekin_work, 1);
- snew(ekindata_.dekindl_work, 1);
+ inputrec_.cos_accel = cosAccel_;
// Group options for annealing output
- inputrec_.opts.ngtc = 3;
+ inputrec_.opts.ngtc = numTempCouplingGroups_;
snew(inputrec_.opts.ref_t, inputrec_.opts.ngtc);
snew(inputrec_.opts.annealing, inputrec_.opts.ngtc);
inputrec_.opts.annealing[0] = SimulatedAnnealing::No;
f_(numAtoms),
inverseMasses_(numAtoms),
inverseMassesPerDim_(numAtoms),
+ kineticEnergyData_(numTCoupleGroups == 0 ? 1 : numTCoupleGroups, 0.0, 1),
numTCoupleGroups_(numTCoupleGroups)
{
mdAtoms_.nr = numAtoms_;
{
mdAtoms_.cTC[i] = 0;
}
- kineticEnergyData_.ngtc = 1;
t_grp_tcstat temperatureCouplingGroupData;
temperatureCouplingGroupData.lambda = 1.0;
- kineticEnergyData_.tcstat.emplace_back(temperatureCouplingGroupData);
+ kineticEnergyData_.tcstat[0] = temperatureCouplingGroupData;
}
else
{
{
mdAtoms_.cTC[i] = i % numTCoupleGroups_;
}
- kineticEnergyData_.ngtc = numTCoupleGroups_;
- for (int i = 0; i < numTCoupleGroups; i++)
+ for (int i = 0; i < numTCoupleGroups_; i++)
{
real tCoupleLambda = 1.0 - (i + 1.0) / 10.0;
t_grp_tcstat temperatureCouplingGroupData;
temperatureCouplingGroupData.lambda = tCoupleLambda;
- kineticEnergyData_.tcstat.emplace_back(temperatureCouplingGroupData);
+ kineticEnergyData_.tcstat[i] = temperatureCouplingGroupData;
}
}
state_.box[ZZ][YY] = 0.0;
state_.box[ZZ][ZZ] = 10.0;
- kineticEnergyData_.cosacc.cos_accel = 0.0;
-
- kineticEnergyData_.nthreads = 1;
- snew(kineticEnergyData_.ekin_work_alloc, kineticEnergyData_.nthreads);
- snew(kineticEnergyData_.ekin_work, kineticEnergyData_.nthreads);
- snew(kineticEnergyData_.dekindl_work, kineticEnergyData_.nthreads);
-
mdAtoms_.homenr = numAtoms_;
mdAtoms_.haveVsites = false;
mdAtoms_.havePartiallyFrozenAtoms = false;
#include "tgroup.h"
-#include <cmath>
-
-#include "gromacs/gmxlib/network.h"
#include "gromacs/math/vec.h"
#include "gromacs/mdlib/coupling.h"
-#include "gromacs/mdlib/gmx_omp_nthreads.h"
-#include "gromacs/mdlib/rbin.h"
#include "gromacs/mdtypes/group.h"
#include "gromacs/mdtypes/inputrec.h"
-#include "gromacs/mdtypes/mdatom.h"
-#include "gromacs/topology/mtop_util.h"
-#include "gromacs/topology/topology.h"
-#include "gromacs/utility/exceptions.h"
-#include "gromacs/utility/fatalerror.h"
-#include "gromacs/utility/futil.h"
-#include "gromacs/utility/smalloc.h"
-
-void init_ekindata(FILE gmx_unused* log, const t_grpopts* opts, gmx_ekindata_t* ekind, real cos_accel)
-{
- int i;
-
- ekind->ngtc = opts->ngtc;
- ekind->tcstat.resize(opts->ngtc);
- /* Set Berendsen tcoupl lambda's to 1,
- * so runs without Berendsen coupling are not affected.
- */
- for (i = 0; i < opts->ngtc; i++)
- {
- ekind->tcstat[i].lambda = 1.0;
- ekind->tcstat[i].vscale_nhc = 1.0;
- ekind->tcstat[i].ekinscaleh_nhc = 1.0;
- ekind->tcstat[i].ekinscalef_nhc = 1.0;
- }
- int nthread = gmx_omp_nthreads_get(emntUpdate);
- ekind->nthreads = nthread;
- snew(ekind->ekin_work_alloc, nthread);
- snew(ekind->ekin_work, nthread);
- snew(ekind->dekindl_work, nthread);
-#pragma omp parallel for num_threads(nthread) schedule(static)
- for (int thread = 0; thread < nthread; thread++)
- {
- try
- {
-#define EKIN_WORK_BUFFER_SIZE 2
- /* Allocate 2 extra elements on both sides, so in single
- * precision we have
- * EKIN_WORK_BUFFER_SIZE*DIM*DIM*sizeof(real) = 72/144 bytes
- * buffer on both sides to avoid cache pollution.
- */
- snew(ekind->ekin_work_alloc[thread], ekind->ngtc + 2 * EKIN_WORK_BUFFER_SIZE);
- ekind->ekin_work[thread] = ekind->ekin_work_alloc[thread] + EKIN_WORK_BUFFER_SIZE;
- /* Nasty hack so we can have the per-thread accumulation
- * variable for dekindl in the same thread-local cache lines
- * as the per-thread accumulation tensors for ekin[fh],
- * because they are accumulated in the same loop. */
- ekind->dekindl_work[thread] = &(ekind->ekin_work[thread][ekind->ngtc][0][0]);
-#undef EKIN_WORK_BUFFER_SIZE
- }
- GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
- }
-
- ekind->cosacc.cos_accel = cos_accel;
-}
real sum_ekin(const t_grpopts* opts, gmx_ekindata_t* ekind, real* dekindlambda, gmx_bool bEkinAveVel, gmx_bool bScaleEkin)
{
#ifndef GMX_MDLIB_TGROUP_H
#define GMX_MDLIB_TGROUP_H
-#include <cstdio>
-
-#include "gromacs/utility/basedefinitions.h"
#include "gromacs/utility/real.h"
-struct gmx_ekindata_t;
-struct t_commrec;
+class gmx_ekindata_t;
struct t_grpopts;
-struct t_mdatoms;
-
-void init_ekindata(FILE* log, const t_grpopts* opts, gmx_ekindata_t* ekind, real cos_accel);
-/* Allocate memory and set the grpnr array. */
-
-void done_ekindata(gmx_ekindata_t* ekind);
-/* Free the memory */
-real sum_ekin(const t_grpopts* opts, gmx_ekindata_t* ekind, real* dekindlambda, gmx_bool bEkinFullStep, gmx_bool bScaleEkin);
+real sum_ekin(const t_grpopts* opts, gmx_ekindata_t* ekind, real* dekindlambda, bool bEkinFullStep, bool bScaleEkin);
/* Sum the group ekins into total ekin and calc temp per group,
* return total temperature.
*/
#include "gromacs/mdlib/mdoutf.h"
#include "gromacs/timing/wallcycle.h"
-struct gmx_ekindata_t;
+class gmx_ekindata_t;
struct gmx_mtop_t;
struct ObservablesHistory;
struct t_commrec;
#include "gromacs/utility/real.h"
class ekinstate_t;
-struct gmx_ekindata_t;
+class gmx_ekindata_t;
struct gmx_enerdata_t;
enum class PbcType;
struct t_fcdata;
#include "gromacs/mdrunutility/handlerestart.h"
#include "gromacs/mdtypes/md_enums.h"
-struct gmx_ekindata_t;
+class gmx_ekindata_t;
struct gmx_enerdata_t;
struct gmx_global_stat;
struct gmx_localtop_t;
#include "gromacs/mdlib/stophandler.h"
class energyhistory_t;
-struct gmx_ekindata_t;
+class gmx_ekindata_t;
struct gmx_enerdata_t;
struct gmx_enfrot;
struct gmx_mtop_t;
"cos_acceleration is only supported by integrator=md");
/* Kinetic energy data */
- gmx_ekindata_t ekind;
- init_ekindata(fplog, &(inputrec->opts), &ekind, inputrec->cos_accel);
+ gmx_ekindata_t ekind(inputrec->opts.ngtc, inputrec->cos_accel, gmx_omp_nthreads_get(emntUpdate));
/* Set up interactive MD (IMD) */
auto imdSession = makeImdSession(inputrec.get(),
class energyhistory_t;
-struct gmx_ekindata_t;
+class gmx_ekindata_t;
struct gmx_enerdata_t;
struct gmx_enfrot;
struct gmx_mtop_t;
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 2019,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "group.h"
+#include "gromacs/utility/exceptions.h"
+
+gmx_ekindata_t::gmx_ekindata_t(int numTempCoupleGroups, real cos_accel, int numThreads) :
+ ngtc(numTempCoupleGroups),
+ nthreads_(numThreads)
+{
+ tcstat.resize(ngtc);
+ /* Set Berendsen tcoupl lambda's to 1,
+ * so runs without Berendsen coupling are not affected.
+ */
+ for (int i = 0; i < ngtc; i++)
+ {
+ tcstat[i].lambda = 1.0;
+ tcstat[i].vscale_nhc = 1.0;
+ tcstat[i].ekinscaleh_nhc = 1.0;
+ tcstat[i].ekinscalef_nhc = 1.0;
+ }
+
+ snew(ekin_work_alloc, nthreads_);
+ snew(ekin_work, nthreads_);
+ snew(dekindl_work, nthreads_);
+
+#pragma omp parallel for num_threads(nthreads_) schedule(static)
+ for (int thread = 0; thread < nthreads_; thread++)
+ {
+ try
+ {
+ constexpr int EKIN_WORK_BUFFER_SIZE = 2;
+ /* Allocate 2 extra elements on both sides, so in single
+ * precision we have
+ * EKIN_WORK_BUFFER_SIZE*DIM*DIM*sizeof(real) = 72/144 bytes
+ * buffer on both sides to avoid cache pollution.
+ */
+ snew(ekin_work_alloc[thread], ngtc + 2 * EKIN_WORK_BUFFER_SIZE);
+ ekin_work[thread] = ekin_work_alloc[thread] + EKIN_WORK_BUFFER_SIZE;
+ /* Nasty hack so we can have the per-thread accumulation
+ * variable for dekindl in the same thread-local cache lines
+ * as the per-thread accumulation tensors for ekin[fh],
+ * because they are accumulated in the same loop. */
+ dekindl_work[thread] = &(ekin_work[thread][ngtc][0][0]);
+ }
+ GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
+ }
+
+ cosacc.cos_accel = cos_accel;
+}
+
gmx_ekindata_t::~gmx_ekindata_t()
{
- for (int i = 0; i < nthreads; i++)
+ for (int i = 0; i < nthreads_; i++)
{
sfree(ekin_work_alloc[i]);
}
real vcos = 0;
};
-struct gmx_ekindata_t
+class gmx_ekindata_t
{
+public:
+ gmx_ekindata_t(int numTempCoupleGroups, real cos_accel, int numThreads);
//! The number of T-coupling groups
- int ngtc = 0;
- //! For size of ekin_work
- int nthreads = 0;
+ int ngtc;
//! T-coupling data
std::vector<t_grp_tcstat> tcstat;
//! Allocated locations for *_work members
t_cos_acc cosacc;
~gmx_ekindata_t();
+
+private:
+ //! For size of ekin_work
+ int nthreads_ = 0;
};
#define GID(igid, jgid, gnr) \
#include "modularsimulatorinterfaces.h"
-struct gmx_ekindata_t;
+class gmx_ekindata_t;
struct gmx_enerdata_t;
struct gmx_mtop_t;
struct ObservablesHistory;