Added EnergyOutputRequestChecker notification for MDModules
[alexxy/gromacs.git] / src / gromacs / utility / mdmodulesnotifiers.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
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.
8  *
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.
13  *
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.
18  *
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.
23  *
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.
31  *
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.
34  */
35 /*! \libinternal \file
36  * \brief
37  * Declares gmx::MDModulesNotifiers.
38  *
39  * \author Christian Blau <blau@kth.se>
40  * \inlibraryapi
41  * \ingroup module_utility
42  */
43
44 #ifndef GMX_UTILITY_MDMODULESNOTIFIERS_H
45 #define GMX_UTILITY_MDMODULESNOTIFIERS_H
46
47 #include <string>
48 #include <vector>
49
50 #include "gromacs/math/arrayrefwithpadding.h"
51 #include "gromacs/math/vectypes.h"
52 #include "gromacs/utility/mdmodulesnotifier.h"
53
54 struct t_commrec;
55 struct gmx_mtop_t;
56 enum class PbcType : int;
57
58 namespace gmx
59 {
60
61 class KeyValueTreeObject;
62 class KeyValueTreeObjectBuilder;
63 class LocalAtomSetManager;
64 class MDLogger;
65 class IndexGroupsAndNames;
66 class SeparatePmeRanksPermitted;
67 struct MDModulesCheckpointReadingDataOnMaster;
68 struct MDModulesCheckpointReadingBroadcast;
69 struct MDModulesWriteCheckpointData;
70
71 /*! \libinternal \brief Check if module outputs energy to a specific field.
72  *
73  * Ensures that energy is output for this module.
74  */
75 struct MDModulesEnergyOutputToDensityFittingRequestChecker
76 {
77     //! Trigger output to density fitting energy field
78     bool energyOutputToDensityFitting_ = false;
79 };
80
81 /*! \libinternal \brief Check if QMMM module outputs energy to a specific field.
82  *
83  * Ensures that energy is output for QMMM module.
84  */
85 struct MDModulesEnergyOutputToQMMMRequestChecker
86 {
87     //! Trigger output to density fitting energy field
88     bool energyOutputToQMMM_ = false;
89 };
90
91 /*! \libinternal
92  * \brief Collect errors for the energy calculation frequency.
93  *
94  * Collect errors regarding energy calculation frequencies as strings that then
95  * may be used to issue errors.
96  *
97  * \note The mdp option "nstcalcenergy" is altered after reading the .mdp input
98  *       and only used in certain integrators, thus this class is to be used
99  *       only after all these operations are done.
100  */
101 class EnergyCalculationFrequencyErrors
102 {
103 public:
104     //! Construct by setting the energy calculation frequency
105     EnergyCalculationFrequencyErrors(int64_t energyCalculationIntervalInSteps) :
106         energyCalculationIntervalInSteps_(energyCalculationIntervalInSteps)
107     {
108     }
109     //! Return the number of steps of an energy calculation interval
110     std::int64_t energyCalculationIntervalInSteps() const
111     {
112         return energyCalculationIntervalInSteps_;
113     }
114     //! Collect error messages
115     void addError(const std::string& errorMessage) { errorMessages_.push_back(errorMessage); }
116     //! Return error messages
117     const std::vector<std::string>& errorMessages() const { return errorMessages_; }
118
119 private:
120     //! The frequency of energy calculations
121     const std::int64_t energyCalculationIntervalInSteps_;
122     //! The error messages
123     std::vector<std::string> errorMessages_;
124 };
125
126 /*! \libinternal \brief Provides the simulation time step in ps.
127  */
128 struct SimulationTimeStep
129 {
130     //! Time step (ps)
131     const double delta_t;
132 };
133
134 /*! \libinternal \brief Provides coordinates and simulation box.
135  */
136 struct CoordinatesAndBoxPreprocessed
137 {
138     ArrayRefWithPadding<RVec> coordinates_;
139     matrix                    box_;
140     PbcType                   pbc_;
141 };
142
143 /*! \libinternal \brief Mdrun input filename.
144  */
145 struct MdRunInputFilename
146 {
147     //! The name of the run input file (.tpr) as output by grompp
148     std::string mdRunFilename_;
149 };
150
151 /*! \libinternal \brief Notification for QM program input filename
152  *  provided by user as command-line argument for grompp
153  */
154 struct QMInputFileName
155 {
156     //! Flag if QM Input File has been provided by user
157     bool hasQMInputFileName_ = false;
158     //! The name of the QM Input file (.inp)
159     std::string qmInputFileName_;
160 };
161
162 /*! \libinternal
163  * \brief Group of notifers to organize that MDModules
164  * can receive callbacks they subscribe to.
165  *
166  * MDModules use members of this struct to subscribe to notifications
167  * of particular events. When the event occurs, the callback provided
168  * by a particular MDModule will be passed a parameter of the
169  * particular type they are interested in.
170  *
171  * Typically, during the setup phase, modules subscribe to notifiers
172  * that interest them by passing callbacks that expect a single parameter
173  * that describes the event. These are stored for later use. See the
174  * sequence diagram that follows:
175    \msc
176 wordwraparcs=true,
177 hscale="2";
178
179 modules [label = "mdModules:\nMDModules"],
180 notifiers [label="notifiers\nMDModulesNotifiers"],
181 notifier [label="exampleNotifier:\nBuildMDModulesNotifier\n<EventX, EventY>::type"],
182 moduleA [label="moduleA"],
183 moduleB [label="moduleB"],
184 moduleC [label="moduleC"];
185
186 modules box moduleC [label = "mdModules creates and owns moduleA, moduleB, and moduleC"];
187 modules =>> notifiers [label="creates"];
188 notifiers =>> notifier [label="creates"];
189 notifier =>> notifiers [label="returns"];
190 notifiers =>> modules [label="returns"];
191
192 modules =>> moduleA [label="provides notifiers"];
193 moduleA =>> moduleA [label="unpacks\nnotifiers.exampleNotifier"];
194 moduleA =>> notifier [label="subscribes with\ncallback(EventX&)"];
195 notifier =>> notifier [label="records subscription\nto EventX"];
196 moduleA =>> notifier [label="subscribes with\ncallback(EventY&)"];
197 notifier =>> notifier [label="records subscription\nto EventY"];
198 moduleA =>> modules [label="returns"];
199
200 modules =>> moduleB [label="provides notifiers"];
201 moduleB =>> moduleB [label="unpacks\nnotifiers.exampleNotifier"];
202 moduleA =>> notifier [label="subscribes with\ncallback(EventY&)"];
203 notifier =>> notifier [label="records subscription\nto EventY"];
204 moduleB =>> modules [label="returns"];
205
206 modules =>> moduleC [label="provides notifiers"];
207 moduleC =>> moduleC [label="unpacks and keeps\nnotifiers.exampleNotifier"];
208 moduleC =>> modules [label="returns"];
209
210    \endmsc
211
212    * When the event occurs later on, the stored callbacks are used to
213    * allow the modules to react. See the following sequence diagram,
214    * which assumes that exampleNotifier was configured as in the
215    * previous sequence diagram.
216
217    \msc
218 wordwraparcs=true,
219 hscale="2";
220
221 moduleC [label="moduleC"],
222 notifier [label="exampleNotifier:\nBuildMDModulesNotifier\n<EventX, EventY>::type"],
223 moduleA [label="moduleA"],
224 moduleB [label="moduleB"];
225
226 moduleC box moduleB [label = "Later, when ModuleC is doing work"];
227 moduleC =>> moduleC [label="generates EventX"];
228 moduleC =>> moduleC [label="generates EventY"];
229 moduleC =>> notifier [label="calls notify(eventX)"];
230 notifier =>> moduleA [label="calls callback(eventX)"];
231 moduleA =>> moduleA [label="reacts to eventX"];
232 moduleA =>> notifier [label="returns"];
233
234 notifier =>> moduleC [label="returns"];
235 moduleC =>> notifier [label="calls notify(eventY)"];
236 notifier =>> moduleA [label="calls callback(eventY)"];
237 moduleA =>> moduleA [label="reacts to eventY"];
238 moduleA =>> notifier [label="returns"];
239 notifier =>> moduleB [label="calls callback(eventY)"];
240 moduleB =>> moduleB [label="reacts to eventY"];
241 moduleB =>> notifier [label="returns"];
242 notifier =>> moduleC [label="returns"];
243    \endmsc
244  *
245  * The template arguments to the members of this struct are the
246  * parameters passed to the callback functions, one type per
247  * callback. Arguments passed as pointers are always meant to be
248  * modified, but never meant to be stored (in line with the policy
249  * everywhere else).
250  *
251  */
252 struct MDModulesNotifiers
253 {
254     /*! \brief Pre-processing callback functions.
255      * const CoordinatesAndBoxPreprocessed Allows modules to access coordinates,
256      *                                box and pbc during grompp
257      * const MDLogger& Allows MdModule to use standard logging class for messages output
258      * EnergyCalculationFrequencyErrors* allows modules to check if they match
259      *                                   their required calculation frequency
260      *                                   and add their error message if needed
261      *                                   to the collected error messages
262      * gmx_mtop_t * Allows modules to modify the topology during pre-processing
263      * IndexGroupsAndNames provides modules with atom indices and their names
264      * KeyValueTreeObjectBuilder enables writing of module internal data to
265      *                           .tpr files.
266      * QMInputFileName Allows QMMM module to know if user provided external QM input file
267      */
268     BuildMDModulesNotifier<const CoordinatesAndBoxPreprocessed,
269                            const MDLogger&,
270                            EnergyCalculationFrequencyErrors*,
271                            gmx_mtop_t*,
272                            const IndexGroupsAndNames&,
273                            KeyValueTreeObjectBuilder,
274                            QMInputFileName>::type preProcessingNotifier_;
275
276     /*! \brief Handles subscribing and calling checkpointing callback functions.
277      *
278      * MDModulesCheckpointReadingDataOnMaster provides modules with their
279      *                                        checkpointed data on the master
280      *                                        node and checkpoint file version
281      * MDModulesCheckpointReadingBroadcast provides modules with a communicator
282      *                                     and the checkpoint file version to
283      *                                     distribute their data
284      * MDModulesWriteCheckpointData provides the modules with a key-value-tree
285      *                              builder to store their checkpoint data and
286      *                              the checkpoint file version
287      */
288     BuildMDModulesNotifier<MDModulesCheckpointReadingDataOnMaster, MDModulesCheckpointReadingBroadcast, MDModulesWriteCheckpointData>::type
289             checkpointingNotifier_;
290
291     /*! \brief Handles subscribing and calling callbacks during simulation setup.
292      *
293      * const KeyValueTreeObject& provides modules with the internal data they
294      *                           wrote to .tpr files
295      * LocalAtomSetManager* enables modules to add atom indices to local atom sets
296      *                      to be managed
297      * const MDLogger& Allows MdModule to use standard logging class for messages output
298      * const gmx_mtop_t& provides the topology of the system to the modules
299      * MDModulesEnergyOutputToDensityFittingRequestChecker* enables modules to
300      *                      report if they want to write their energy output
301      *                      to the density fitting field in the energy files
302      * MDModulesEnergyOutputToQMMMRequestChecker* enables QMMM module to
303      *                      report if it want to write their energy output
304      *                      to the "Quantum En." field in the energy files
305      * SeparatePmeRanksPermitted* enables modules to report if they want
306      *                      to disable dedicated PME ranks
307      * const PbcType& provides modules with the periodic boundary condition type
308      *                that is used during the simulation
309      * const SimulationTimeStep& provides modules with the simulation time-step
310      *                           that allows them to interconvert between step
311      *                           time information
312      * const t_commrec& provides a communicator to the modules during simulation
313      *                  setup
314      * MdRunInputFilename Allows modules to know .tpr filename during mdrun
315      */
316     BuildMDModulesNotifier<const KeyValueTreeObject&,
317                            LocalAtomSetManager*,
318                            const MDLogger&,
319                            const gmx_mtop_t&,
320                            MDModulesEnergyOutputToDensityFittingRequestChecker*,
321                            MDModulesEnergyOutputToQMMMRequestChecker*,
322                            SeparatePmeRanksPermitted*,
323                            const PbcType&,
324                            const SimulationTimeStep&,
325                            const t_commrec&,
326                            MdRunInputFilename>::type simulationSetupNotifier_;
327 };
328
329 } // namespace gmx
330
331 #endif