*/
class DensityFitting final : public IMDModule
{
+
public:
- /*! \brief Construct the density fitting module.
+ //! Construct the density fitting module.
+ explicit DensityFitting() = default;
+
+ /*! \brief Request to be notified during pre-processing.
*
* \param[in] notifier allows the module to subscribe to notifications from MdModules.
*
* - storing its internal parameters in a tpr file by writing to a
* key-value-tree during pre-processing by a function taking a
* KeyValueTreeObjectBuilder as parameter
- * - reading its internal parameters from a key-value-tree during
- * simulation setup by taking a const KeyValueTreeObject & parameter
- * - constructing local atom sets in the simulation parameter setup
- * by taking a LocalAtomSetManager * as parameter
- * - the type of periodic boundary conditions that are used
- * by taking a PeriodicBoundaryConditionType as parameter
- * - the writing of checkpoint data
- * by taking a MdModulesWriteCheckpointData as parameter
- * - the reading of checkpoint data
- * by taking a MdModulesCheckpointReadingDataOnMaster as parameter
- * - the broadcasting of checkpoint data
- * by taking MdModulesCheckpointReadingBroadcast as parameter
*/
- explicit DensityFitting(MdModulesNotifier* notifier)
+ void subscribeToPreProcessingNotifications(MdModulesNotifier* notifier) override
{
// Callbacks for several kinds of MdModuleNotification are created
// and subscribed, and will be dispatched correctly at run time
// based on the type of the parameter required by the lambda.
+ if (!densityFittingOptions_.active())
+ {
+ return;
+ }
+
// Setting the atom group indices from index group string
const auto setFitGroupIndicesFunction = [this](const IndexGroupsAndNames& indexGroupsAndNames) {
densityFittingOptions_.setFitGroupIndices(indexGroupsAndNames);
};
notifier->preProcessingNotifications_.subscribe(writeInternalParametersFunction);
- // Reading internal parameters during simulation setup
- const auto readInternalParametersFunction = [this](const KeyValueTreeObject& tree) {
- densityFittingOptions_.readInternalParametersFromKvt(tree);
- };
- notifier->simulationSetupNotifications_.subscribe(readInternalParametersFunction);
-
// Checking for consistency with all .mdp options
const auto checkEnergyCaluclationFrequencyFunction =
[this](EnergyCalculationFrequencyErrors* energyCalculationFrequencyErrors) {
densityFittingOptions_.checkEnergyCaluclationFrequency(energyCalculationFrequencyErrors);
};
notifier->preProcessingNotifications_.subscribe(checkEnergyCaluclationFrequencyFunction);
+ }
+
+ /*! \brief Request to be notified.
+ * The density fitting code subscribes to these notifications:
+ * - reading its internal parameters from a key-value-tree during
+ * simulation setup by taking a const KeyValueTreeObject & parameter
+ * - constructing local atom sets in the simulation parameter setup
+ * by taking a LocalAtomSetManager * as parameter
+ * - the type of periodic boundary conditions that are used
+ * by taking a PeriodicBoundaryConditionType as parameter
+ * - the writing of checkpoint data
+ * by taking a MdModulesWriteCheckpointData as parameter
+ * - the reading of checkpoint data
+ * by taking a MdModulesCheckpointReadingDataOnMaster as parameter
+ * - the broadcasting of checkpoint data
+ * by taking MdModulesCheckpointReadingBroadcast as parameter
+ */
+ void subscribeToSimulationSetupNotifications(MdModulesNotifier* notifier) override
+ {
+ if (!densityFittingOptions_.active())
+ {
+ return;
+ }
+
+ // Reading internal parameters during simulation setup
+ const auto readInternalParametersFunction = [this](const KeyValueTreeObject& tree) {
+ densityFittingOptions_.readInternalParametersFromKvt(tree);
+ };
+ notifier->simulationSetupNotifications_.subscribe(readInternalParametersFunction);
// constructing local atom sets during simulation setup
const auto setLocalAtomSetFunction = [this](LocalAtomSetManager* localAtomSetManager) {
*/
void constructLocalAtomSet(LocalAtomSetManager* localAtomSetManager)
{
- if (densityFittingOptions_.active())
- {
- LocalAtomSet atomSet =
- localAtomSetManager->add(densityFittingOptions_.buildParameters().indices_);
- densityFittingSimulationParameters_.setLocalAtomSet(atomSet);
- }
+ LocalAtomSet atomSet = localAtomSetManager->add(densityFittingOptions_.buildParameters().indices_);
+ densityFittingSimulationParameters_.setLocalAtomSet(atomSet);
}
/*! \brief Request energy output to energy file during simulation.
*/
void writeCheckpointData(MdModulesWriteCheckpointData checkpointWriting)
{
- if (densityFittingOptions_.active())
- {
- const DensityFittingForceProviderState& state = forceProvider_->stateToCheckpoint();
- checkpointWriting.builder_.addValue<std::int64_t>(
- DensityFittingModuleInfo::name_ + "-stepsSinceLastCalculation",
- state.stepsSinceLastCalculation_);
- checkpointWriting.builder_.addValue<real>(
- DensityFittingModuleInfo::name_ + "-adaptiveForceConstantScale",
- state.adaptiveForceConstantScale_);
- KeyValueTreeObjectBuilder exponentialMovingAverageKvtEntry =
- checkpointWriting.builder_.addObject(DensityFittingModuleInfo::name_
- + "-exponentialMovingAverageState");
- exponentialMovingAverageStateAsKeyValueTree(exponentialMovingAverageKvtEntry,
- state.exponentialMovingAverageState_);
- }
+ const DensityFittingForceProviderState& state = forceProvider_->stateToCheckpoint();
+ checkpointWriting.builder_.addValue<std::int64_t>(
+ DensityFittingModuleInfo::name_ + "-stepsSinceLastCalculation",
+ state.stepsSinceLastCalculation_);
+ checkpointWriting.builder_.addValue<real>(
+ DensityFittingModuleInfo::name_ + "-adaptiveForceConstantScale",
+ state.adaptiveForceConstantScale_);
+ KeyValueTreeObjectBuilder exponentialMovingAverageKvtEntry = checkpointWriting.builder_.addObject(
+ DensityFittingModuleInfo::name_ + "-exponentialMovingAverageState");
+ exponentialMovingAverageStateAsKeyValueTree(exponentialMovingAverageKvtEntry,
+ state.exponentialMovingAverageState_);
}
/*! \brief Read the internal parameters from the checkpoint file on master
*/
void readCheckpointDataOnMaster(MdModulesCheckpointReadingDataOnMaster checkpointReading)
{
- if (densityFittingOptions_.active())
+ if (checkpointReading.checkpointedData_.keyExists(DensityFittingModuleInfo::name_
+ + "-stepsSinceLastCalculation"))
{
- if (checkpointReading.checkpointedData_.keyExists(DensityFittingModuleInfo::name_
- + "-stepsSinceLastCalculation"))
- {
- densityFittingState_.stepsSinceLastCalculation_ =
- checkpointReading
- .checkpointedData_[DensityFittingModuleInfo::name_
- + "-stepsSinceLastCalculation"]
- .cast<std::int64_t>();
- }
- if (checkpointReading.checkpointedData_.keyExists(DensityFittingModuleInfo::name_
- + "-adaptiveForceConstantScale"))
- {
- densityFittingState_.adaptiveForceConstantScale_ =
- checkpointReading
- .checkpointedData_[DensityFittingModuleInfo::name_
- + "-adaptiveForceConstantScale"]
- .cast<real>();
- }
- if (checkpointReading.checkpointedData_.keyExists(DensityFittingModuleInfo::name_
- + "-exponentialMovingAverageState"))
- {
- densityFittingState_.exponentialMovingAverageState_ = exponentialMovingAverageStateFromKeyValueTree(
- checkpointReading
- .checkpointedData_[DensityFittingModuleInfo::name_ + "-exponentialMovingAverageState"]
- .asObject());
- }
+ densityFittingState_.stepsSinceLastCalculation_ =
+ checkpointReading
+ .checkpointedData_[DensityFittingModuleInfo::name_
+ + "-stepsSinceLastCalculation"]
+ .cast<std::int64_t>();
+ }
+ if (checkpointReading.checkpointedData_.keyExists(DensityFittingModuleInfo::name_
+ + "-adaptiveForceConstantScale"))
+ {
+ densityFittingState_.adaptiveForceConstantScale_ =
+ checkpointReading
+ .checkpointedData_[DensityFittingModuleInfo::name_
+ + "-adaptiveForceConstantScale"]
+ .cast<real>();
+ }
+ if (checkpointReading.checkpointedData_.keyExists(DensityFittingModuleInfo::name_
+ + "-exponentialMovingAverageState"))
+ {
+ densityFittingState_.exponentialMovingAverageState_ = exponentialMovingAverageStateFromKeyValueTree(
+ checkpointReading
+ .checkpointedData_[DensityFittingModuleInfo::name_ + "-exponentialMovingAverageState"]
+ .asObject());
}
}
*/
void broadcastCheckpointData(MdModulesCheckpointReadingBroadcast checkpointBroadcast)
{
- if (densityFittingOptions_.active())
+ if (PAR(&(checkpointBroadcast.cr_)))
{
- if (PAR(&(checkpointBroadcast.cr_)))
- {
- block_bc(&(checkpointBroadcast.cr_), densityFittingState_.stepsSinceLastCalculation_);
- block_bc(&(checkpointBroadcast.cr_), densityFittingState_.adaptiveForceConstantScale_);
- block_bc(&(checkpointBroadcast.cr_), densityFittingState_.exponentialMovingAverageState_);
- }
+ block_bc(&(checkpointBroadcast.cr_), densityFittingState_.stepsSinceLastCalculation_);
+ block_bc(&(checkpointBroadcast.cr_), densityFittingState_.adaptiveForceConstantScale_);
+ block_bc(&(checkpointBroadcast.cr_), densityFittingState_.exponentialMovingAverageState_);
}
}
} // namespace
-std::unique_ptr<IMDModule> DensityFittingModuleInfo::create(MdModulesNotifier* notifier)
+std::unique_ptr<IMDModule> DensityFittingModuleInfo::create()
{
- return std::make_unique<DensityFitting>(notifier);
+ return std::make_unique<DensityFitting>();
}
const std::string DensityFittingModuleInfo::name_ = "density-guided-simulation";
* Fitting an all-atom structure into an experimental cryo-EM density map is a
* typical application.
*/
- static std::unique_ptr<IMDModule> create(MdModulesNotifier* notifier);
+ static std::unique_ptr<IMDModule> create();
//! The name of the module
static const std::string name_;
};
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2015,2016,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,2017,2018,2019,2020, 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.
void calculateForces(const ForceProviderInput& forceProviderInput,
ForceProviderOutput* forceProviderOutput) override;
+ void subscribeToSimulationSetupNotifications(MdModulesNotifier* /* notifier */) override {}
+ void subscribeToPreProcessingNotifications(MdModulesNotifier* /* notifier */) override {}
+
private:
//! Return whether or not to apply a field
bool isActive() const;
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020, 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.
{
KeyValueTreeObject mdpOptionsTree = mdpValueBuilder_.build();
- densityFittingModule_ = DensityFittingModuleInfo::create(¬ifier_);
+ densityFittingModule_ = DensityFittingModuleInfo::create();
// set up options
Options densityFittingModuleOptions;
protected:
KeyValueTreeBuilder mdpValueBuilder_;
- MdModulesNotifier notifier_;
ForceProviders densityFittingForces_;
std::unique_ptr<IMDModule> densityFittingModule_;
};
}
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
+ // Now that the MdModules have their options assigned from get_ir, subscribe
+ // to eventual notifications during pre-processing their data
+ mdModules.subscribeToPreProcessingNotifications();
+
+
if (bVerbose)
{
GMX_LOG(logger.info)
IMdpOptionProvider* mdpOptionProvider() override { return nullptr; }
IMDOutputProvider* outputProvider() override { return nullptr; }
void initForceProviders(ForceProviders* /* forceProviders */) override {}
+ void subscribeToSimulationSetupNotifications(MdModulesNotifier* /* notifier */) override {}
+ void subscribeToPreProcessingNotifications(MdModulesNotifier* /* notifier */) override {}
};
std::unique_ptr<IMDModule> createInteractiveMolecularDynamicsModule()
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017,2018,2019,2020, 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.
{
public:
Impl() :
- densityFitting_(DensityFittingModuleInfo::create(¬ifier_)),
+ densityFitting_(DensityFittingModuleInfo::create()),
field_(createElectricFieldModule()),
imd_(createInteractiveMolecularDynamicsModule()),
swapCoordinates_(createSwapCoordinatesModule())
return impl_->forceProviders_.get();
}
+void MDModules::subscribeToPreProcessingNotifications()
+{
+ impl_->densityFitting_->subscribeToPreProcessingNotifications(&impl_->notifier_);
+}
+
+void MDModules::subscribeToSimulationSetupNotifications()
+{
+ impl_->densityFitting_->subscribeToSimulationSetupNotifications(&impl_->notifier_);
+}
+
void MDModules::add(std::shared_ptr<gmx::IMDModule> module)
{
impl_->modules_.emplace_back(std::move(module));
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016,2017,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017,2018,2019,2020, 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.
*/
ForceProviders* initForceProviders();
+ /*! \brief Subscribe MdModules to simulation setup notifications.
+ *
+ * Allows MdModules to subscribe to notifications that are called back
+ * during the set up of an MD simulation, after the options were
+ * assigned to the modules.
+ */
+ void subscribeToSimulationSetupNotifications();
+
+ /*! \brief Subscribe MdModules to notifications during pre-processing.
+ *
+ * Allows MdModules to subscribe to notifications that are called back
+ * during pre processing an MD simulation, after the options were
+ * assigned to the modules.
+ */
+ void subscribeToPreProcessingNotifications();
+
/*!
* \brief Add a module to the container.
*
// TODO: Error handling
mdModules_->assignOptionsToModules(*inputrec->params, nullptr);
+ // now that the MdModules know their options, they know which callbacks to sign up to
+ mdModules_->subscribeToSimulationSetupNotifications();
const auto& mdModulesNotifier = mdModules_->notifier().simulationSetupNotifications_;
if (inputrec->internalParameters != nullptr)
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2017,2019, by the GROMACS development team, led by
+ * Copyright (c) 2017,2019,2020, 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.
class ForceProviders;
class IMDOutputProvider;
class IMdpOptionProvider;
+struct MdModulesNotifier;
/*! \libinternal \brief
* Extension module for \Gromacs simulations.
virtual IMDOutputProvider* outputProvider() = 0;
//! Initializes force providers from this module.
virtual void initForceProviders(ForceProviders* forceProviders) = 0;
+ //! Subscribe to simulation setup notifications
+ virtual void subscribeToSimulationSetupNotifications(MdModulesNotifier* notifier) = 0;
+ //! Subscribe to pre processing notifications
+ virtual void subscribeToPreProcessingNotifications(MdModulesNotifier* notifier) = 0;
};
} // namespace gmx
return newModule;
}
+void RestraintMDModule::subscribeToSimulationSetupNotifications(MdModulesNotifier* /*notifier*/) {}
+
+void RestraintMDModule::subscribeToPreProcessingNotifications(MdModulesNotifier* /*notifier*/) {}
+
// private constructor to implement static create() method.
RestraintMDModule::RestraintMDModule(std::unique_ptr<RestraintMDModuleImpl> restraint) :
impl_{ std::move(restraint) }
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020, 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.
// Forward declaration to allow opaque pointer to library internal class.
class RestraintMDModuleImpl;
+struct MdModulesNotifier;
/*! \libinternal \ingroup module_restraint
* \brief MDModule wrapper for Restraint implementations.
*/
void initForceProviders(ForceProviders* forceProviders) override;
+ //! Subscribe to simulation setup notifications
+ void subscribeToSimulationSetupNotifications(MdModulesNotifier* notifier) override;
+ //! Subscribe to pre processing notifications
+ void subscribeToPreProcessingNotifications(MdModulesNotifier* notifier) override;
+
private:
/*!
* \brief Private implementation opaque pointer.
IMdpOptionProvider* mdpOptionProvider() override { return nullptr; }
IMDOutputProvider* outputProvider() override { return nullptr; }
void initForceProviders(ForceProviders* /* forceProviders */) override {}
+ void subscribeToSimulationSetupNotifications(MdModulesNotifier* /* notifier */) override {}
+ void subscribeToPreProcessingNotifications(MdModulesNotifier* /* notifier */) override {}
};
std::unique_ptr<IMDModule> createSwapCoordinatesModule()