2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
5 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 * and including many others, as listed in the AUTHORS file in the
7 * top-level source directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
35 /*! \libinternal \file
37 * Declares gmx::MDModulesNotifiers.
39 * \author Christian Blau <blau@kth.se>
41 * \ingroup module_utility
44 #ifndef GMX_UTILITY_MDMODULESNOTIFIERS_H
45 #define GMX_UTILITY_MDMODULESNOTIFIERS_H
50 #include "gromacs/math/arrayrefwithpadding.h"
51 #include "gromacs/math/vectypes.h"
52 #include "gromacs/utility/mdmodulesnotifier.h"
57 enum class PbcType : int;
62 class KeyValueTreeObject;
63 class KeyValueTreeObjectBuilder;
64 class LocalAtomSetManager;
66 class IndexGroupsAndNames;
67 class SeparatePmeRanksPermitted;
68 struct MDModulesCheckpointReadingDataOnMaster;
69 struct MDModulesCheckpointReadingBroadcast;
70 struct MDModulesWriteCheckpointData;
72 /*! \libinternal \brief Check if module outputs energy to a specific field.
74 * Ensures that energy is output for this module.
76 struct MDModulesEnergyOutputToDensityFittingRequestChecker
78 //! Trigger output to density fitting energy field
79 bool energyOutputToDensityFitting_ = false;
82 /*! \libinternal \brief Check if QMMM module outputs energy to a specific field.
84 * Ensures that energy is output for QMMM module.
86 struct MDModulesEnergyOutputToQMMMRequestChecker
88 //! Trigger output to density fitting energy field
89 bool energyOutputToQMMM_ = false;
93 * \brief Collect errors for the energy calculation frequency.
95 * Collect errors regarding energy calculation frequencies as strings that then
96 * may be used to issue errors.
98 * \note The mdp option "nstcalcenergy" is altered after reading the .mdp input
99 * and only used in certain integrators, thus this class is to be used
100 * only after all these operations are done.
102 class EnergyCalculationFrequencyErrors
105 //! Construct by setting the energy calculation frequency
106 EnergyCalculationFrequencyErrors(int64_t energyCalculationIntervalInSteps) :
107 energyCalculationIntervalInSteps_(energyCalculationIntervalInSteps)
110 //! Return the number of steps of an energy calculation interval
111 std::int64_t energyCalculationIntervalInSteps() const
113 return energyCalculationIntervalInSteps_;
115 //! Collect error messages
116 void addError(const std::string& errorMessage) { errorMessages_.push_back(errorMessage); }
117 //! Return error messages
118 const std::vector<std::string>& errorMessages() const { return errorMessages_; }
121 //! The frequency of energy calculations
122 const std::int64_t energyCalculationIntervalInSteps_;
123 //! The error messages
124 std::vector<std::string> errorMessages_;
127 /*! \libinternal \brief Provides the simulation time step in ps.
129 struct SimulationTimeStep
132 const double delta_t;
135 /*! \libinternal \brief Provides coordinates and simulation box.
137 struct CoordinatesAndBoxPreprocessed
139 ArrayRefWithPadding<RVec> coordinates_;
144 /*! \libinternal \brief Mdrun input filename.
146 struct MdRunInputFilename
148 //! The name of the run input file (.tpr) as output by grompp
149 std::string mdRunFilename_;
152 /*! \libinternal \brief Notification for QM program input filename
153 * provided by user as command-line argument for grompp
155 struct QMInputFileName
157 //! Flag if QM Input File has been provided by user
158 bool hasQMInputFileName_ = false;
159 //! The name of the QM Input file (.inp)
160 std::string qmInputFileName_;
164 * \brief Group of notifers to organize that MDModules
165 * can receive callbacks they subscribe to.
167 * MDModules use members of this struct to subscribe to notifications
168 * of particular events. When the event occurs, the callback provided
169 * by a particular MDModule will be passed a parameter of the
170 * particular type they are interested in.
172 * Typically, during the setup phase, modules subscribe to notifiers
173 * that interest them by passing callbacks that expect a single parameter
174 * that describes the event. These are stored for later use. See the
175 * sequence diagram that follows:
180 modules [label = "mdModules:\nMDModules"],
181 notifiers [label="notifiers\nMDModulesNotifiers"],
182 notifier [label="exampleNotifier:\nBuildMDModulesNotifier\n<EventX, EventY>::type"],
183 moduleA [label="moduleA"],
184 moduleB [label="moduleB"],
185 moduleC [label="moduleC"];
187 modules box moduleC [label = "mdModules creates and owns moduleA, moduleB, and moduleC"];
188 modules =>> notifiers [label="creates"];
189 notifiers =>> notifier [label="creates"];
190 notifier =>> notifiers [label="returns"];
191 notifiers =>> modules [label="returns"];
193 modules =>> moduleA [label="provides notifiers"];
194 moduleA =>> moduleA [label="unpacks\nnotifiers.exampleNotifier"];
195 moduleA =>> notifier [label="subscribes with\ncallback(EventX&)"];
196 notifier =>> notifier [label="records subscription\nto EventX"];
197 moduleA =>> notifier [label="subscribes with\ncallback(EventY&)"];
198 notifier =>> notifier [label="records subscription\nto EventY"];
199 moduleA =>> modules [label="returns"];
201 modules =>> moduleB [label="provides notifiers"];
202 moduleB =>> moduleB [label="unpacks\nnotifiers.exampleNotifier"];
203 moduleA =>> notifier [label="subscribes with\ncallback(EventY&)"];
204 notifier =>> notifier [label="records subscription\nto EventY"];
205 moduleB =>> modules [label="returns"];
207 modules =>> moduleC [label="provides notifiers"];
208 moduleC =>> moduleC [label="unpacks and keeps\nnotifiers.exampleNotifier"];
209 moduleC =>> modules [label="returns"];
213 * When the event occurs later on, the stored callbacks are used to
214 * allow the modules to react. See the following sequence diagram,
215 * which assumes that exampleNotifier was configured as in the
216 * previous sequence diagram.
222 moduleC [label="moduleC"],
223 notifier [label="exampleNotifier:\nBuildMDModulesNotifier\n<EventX, EventY>::type"],
224 moduleA [label="moduleA"],
225 moduleB [label="moduleB"];
227 moduleC box moduleB [label = "Later, when ModuleC is doing work"];
228 moduleC =>> moduleC [label="generates EventX"];
229 moduleC =>> moduleC [label="generates EventY"];
230 moduleC =>> notifier [label="calls notify(eventX)"];
231 notifier =>> moduleA [label="calls callback(eventX)"];
232 moduleA =>> moduleA [label="reacts to eventX"];
233 moduleA =>> notifier [label="returns"];
235 notifier =>> moduleC [label="returns"];
236 moduleC =>> notifier [label="calls notify(eventY)"];
237 notifier =>> moduleA [label="calls callback(eventY)"];
238 moduleA =>> moduleA [label="reacts to eventY"];
239 moduleA =>> notifier [label="returns"];
240 notifier =>> moduleB [label="calls callback(eventY)"];
241 moduleB =>> moduleB [label="reacts to eventY"];
242 moduleB =>> notifier [label="returns"];
243 notifier =>> moduleC [label="returns"];
246 * The template arguments to the members of this struct are the
247 * parameters passed to the callback functions, one type per
248 * callback. Arguments passed as pointers are always meant to be
249 * modified, but never meant to be stored (in line with the policy
253 struct MDModulesNotifiers
255 /*! \brief Pre-processing callback functions.
256 * CoordinatesAndBoxPreprocessed Allows modules to access coordinates,
257 * box and pbc during grompp
258 * MDLogger Allows MdModule to use standard logging class for messages output
259 * warninp* Allows modules to make grompp warnings, notes and errors
260 * EnergyCalculationFrequencyErrors* allows modules to check if they match
261 * their required calculation frequency
262 * and add their error message if needed
263 * to the collected error messages
264 * gmx_mtop_t* Allows modules to modify the topology during pre-processing
265 * IndexGroupsAndNames provides modules with atom indices and their names
266 * KeyValueTreeObjectBuilder enables writing of module internal data to
268 * QMInputFileName Allows QMMM module to know if user provided external QM input file
270 BuildMDModulesNotifier<const CoordinatesAndBoxPreprocessed&,
273 EnergyCalculationFrequencyErrors*,
275 const IndexGroupsAndNames&,
276 KeyValueTreeObjectBuilder,
277 const QMInputFileName&>::type preProcessingNotifier_;
279 /*! \brief Handles subscribing and calling checkpointing callback functions.
281 * MDModulesCheckpointReadingDataOnMaster provides modules with their
282 * checkpointed data on the master
283 * node and checkpoint file version
284 * MDModulesCheckpointReadingBroadcast provides modules with a communicator
285 * and the checkpoint file version to
286 * distribute their data
287 * MDModulesWriteCheckpointData provides the modules with a key-value-tree
288 * builder to store their checkpoint data and
289 * the checkpoint file version
291 BuildMDModulesNotifier<MDModulesCheckpointReadingDataOnMaster, MDModulesCheckpointReadingBroadcast, MDModulesWriteCheckpointData>::type
292 checkpointingNotifier_;
294 /*! \brief Handles subscribing and calling callbacks during simulation setup.
296 * const KeyValueTreeObject& provides modules with the internal data they
297 * wrote to .tpr files
298 * LocalAtomSetManager* enables modules to add atom indices to local atom sets
300 * const MDLogger& Allows MdModule to use standard logging class for messages output
301 * const gmx_mtop_t& provides the topology of the system to the modules
302 * MDModulesEnergyOutputToDensityFittingRequestChecker* enables modules to
303 * report if they want to write their energy output
304 * to the density fitting field in the energy files
305 * MDModulesEnergyOutputToQMMMRequestChecker* enables QMMM module to
306 * report if it want to write their energy output
307 * to the "Quantum En." field in the energy files
308 * SeparatePmeRanksPermitted* enables modules to report if they want
309 * to disable dedicated PME ranks
310 * const PbcType& provides modules with the periodic boundary condition type
311 * that is used during the simulation
312 * const SimulationTimeStep& provides modules with the simulation time-step
313 * that allows them to interconvert between step
315 * const t_commrec& provides a communicator to the modules during simulation
317 * const MdRunInputFilename& Allows modules to know .tpr filename during mdrun
319 BuildMDModulesNotifier<const KeyValueTreeObject&,
320 LocalAtomSetManager*,
323 MDModulesEnergyOutputToDensityFittingRequestChecker*,
324 MDModulesEnergyOutputToQMMMRequestChecker*,
325 SeparatePmeRanksPermitted*,
327 const SimulationTimeStep&,
329 const MdRunInputFilename&>::type simulationSetupNotifier_;