748241617bea4daa88b6bc8eb9b764393e9b89e8
[alexxy/gromacs.git] / src / gromacs / mdtypes / iforceprovider.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2016,2017,2018,2019,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::IForceProvider and ForceProviders.
38  *
39  * See \ref page_mdmodules for an overview of this and associated interfaces.
40  *
41  * \author Teemu Murtola <teemu.murtola@gmail.com>
42  * \author Carsten Kutzner <ckutzne@gwdg.de>
43  * \inlibraryapi
44  * \ingroup module_mdtypes
45  */
46 #ifndef GMX_MDTYPES_IFORCEPROVIDER_H
47 #define GMX_MDTYPES_IFORCEPROVIDER_H
48
49 #include <memory>
50
51 #include "gromacs/math/vec.h"
52 #include "gromacs/utility/arrayref.h"
53 #include "gromacs/utility/gmxassert.h"
54
55 struct gmx_enerdata_t;
56 struct t_commrec;
57 struct t_forcerec;
58 struct t_mdatoms;
59
60 namespace gmx
61 {
62
63 template<typename T>
64 class ArrayRef;
65 class ForceWithVirial;
66
67
68 /*! \libinternal \brief
69  * Helper struct that bundles data for passing it over to the force providers
70  *
71  * This is a short-lived container that bundles up all necessary input data for the
72  * force providers. Its only purpose is to allow calling forceProviders->calculateForces()
73  * with just two arguments, one being the container for the input data,
74  * the other the container for the output data.
75  *
76  * Both ForceProviderInput as well as ForceProviderOutput only package existing
77  * data structs together for handing it over to calculateForces(). Apart from the
78  * POD entries they own nothing.
79  */
80 class ForceProviderInput
81 {
82 public:
83     /*! \brief Constructor assembles all necessary force provider input data
84      *
85      * \param[in]  x        Atomic positions
86      * \param[in]  cr       Communication record structure
87      * \param[in]  box      The simulation box
88      * \param[in]  time     The current time in the simulation
89      * \param[in]  mdatoms  The atomic data
90      */
91     ForceProviderInput(ArrayRef<const RVec> x,
92                        const t_mdatoms&     mdatoms,
93                        double               time,
94                        const matrix         box,
95                        const t_commrec&     cr) :
96         x_(x),
97         mdatoms_(mdatoms),
98         t_(time),
99         cr_(cr)
100     {
101         copy_mat(box, box_);
102     }
103
104     ArrayRef<const RVec> x_;       //!< The atomic positions
105     const t_mdatoms&     mdatoms_; //!< Atomic data
106     double               t_;       //!< The current time in the simulation
107     matrix               box_ = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }; //!< The simulation box
108     const t_commrec&     cr_; //!< Communication record structure
109 };
110
111 /*! \brief Take pointer, check if valid, return reference
112  */
113 template<class T>
114 T& makeRefFromPointer(T* ptr)
115 {
116     GMX_ASSERT(ptr != nullptr, "got null pointer");
117     return *ptr;
118 }
119
120 /*! \libinternal \brief
121  * Helper struct bundling the output data of a force provider
122  *
123  * Same as for the ForceProviderInput class, but these variables can be written as well.
124  */
125 class ForceProviderOutput
126 {
127 public:
128     /*! \brief Constructor assembles all necessary force provider output data
129      *
130      * \param[in,out]  forceWithVirial  Container for force and virial
131      * \param[in,out]  enerd            Structure containing energy data
132      */
133     ForceProviderOutput(ForceWithVirial* forceWithVirial, gmx_enerdata_t* enerd) :
134         forceWithVirial_(makeRefFromPointer(forceWithVirial)),
135         enerd_(makeRefFromPointer(enerd))
136     {
137     }
138
139     ForceWithVirial& forceWithVirial_; //!< Container for force and virial
140     gmx_enerdata_t&  enerd_;           //!< Structure containing energy data
141 };
142
143
144 /*! \libinternal \brief
145  * Interface for a component that provides forces during MD.
146  *
147  * Modules implementing IMDModule generally implement this internally, and use
148  * IMDModule::initForceProviders() to register their implementation in
149  * ForceProviders.
150  *
151  * The interface most likely requires additional generalization for use in
152  * other modules than the current electric field implementation.
153  *
154  * The forces that are produced by force providers are not taken into account
155  * in the calculation of the virial. When applicable, the provider should
156  * compute its own virial contribution.
157  *
158  * \inlibraryapi
159  * \ingroup module_mdtypes
160  */
161 class IForceProvider
162 {
163 public:
164     /*! \brief
165      * Computes forces.
166      *
167      * \param[in]    forceProviderInput    struct that collects input data for the force providers
168      * \param[in,out] forceProviderOutput   struct that collects output data of the force providers
169      */
170     virtual void calculateForces(const ForceProviderInput& forceProviderInput,
171                                  ForceProviderOutput*      forceProviderOutput) = 0;
172
173 protected:
174     ~IForceProvider() {}
175 };
176
177 /*! \libinternal \brief
178  * Evaluates forces from a collection of gmx::IForceProvider.
179  *
180  * \inlibraryapi
181  * \ingroup module_mdtypes
182  */
183 class ForceProviders
184 {
185 public:
186     ForceProviders();
187     ~ForceProviders();
188
189     /*! \brief
190      * Adds a provider.
191      */
192     void addForceProvider(gmx::IForceProvider* provider);
193
194     //! Whether there are modules added.
195     bool hasForceProvider() const;
196
197     //! Computes forces.
198     void calculateForces(const gmx::ForceProviderInput& forceProviderInput,
199                          gmx::ForceProviderOutput*      forceProviderOutput) const;
200
201 private:
202     class Impl;
203
204     std::unique_ptr<Impl> impl_;
205 };
206
207 } // namespace gmx
208
209 #endif