3006bf88e971914fe5786a54ed72b97cde1b2a5f
[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
59 namespace gmx
60 {
61
62 template<typename T>
63 class ArrayRef;
64 class ForceWithVirial;
65
66
67 /*! \libinternal \brief
68  * Helper struct that bundles data for passing it over to the force providers
69  *
70  * This is a short-lived container that bundles up all necessary input data for the
71  * force providers. Its only purpose is to allow calling forceProviders->calculateForces()
72  * with just two arguments, one being the container for the input data,
73  * the other the container for the output data.
74  *
75  * Both ForceProviderInput as well as ForceProviderOutput only package existing
76  * data structs together for handing it over to calculateForces(). Apart from the
77  * POD entries they own nothing.
78  */
79 class ForceProviderInput
80 {
81 public:
82     /*! \brief Constructor assembles all necessary force provider input data
83      *
84      * \param[in]  x        Atomic positions.
85      * \param[in]  homenr   Number of atoms on the domain.
86      * \param[in]  chargeA  Atomic charges for atoms on the domain.
87      * \param[in]  massT    Atomic masses for atoms on the domain.
88      * \param[in]  time     The current time in the simulation.
89      * \param[in]  box      The simulation box.
90      * \param[in]  cr       Communication record structure.
91      */
92     ForceProviderInput(ArrayRef<const RVec> x,
93                        int                  homenr,
94                        ArrayRef<const real> chargeA,
95                        ArrayRef<const real> massT,
96                        double               time,
97                        const matrix         box,
98                        const t_commrec&     cr) :
99         x_(x),
100         homenr_(homenr),
101         chargeA_(chargeA),
102         massT_(massT),
103         t_(time),
104         cr_(cr)
105     {
106         copy_mat(box, box_);
107     }
108
109     ArrayRef<const RVec> x_; //!< The atomic positions
110     int                  homenr_;
111     ArrayRef<const real> chargeA_;
112     ArrayRef<const real> massT_;
113     double               t_; //!< The current time in the simulation
114     matrix               box_ = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }; //!< The simulation box
115     const t_commrec&     cr_; //!< Communication record structure
116 };
117
118 /*! \brief Take pointer, check if valid, return reference
119  */
120 template<class T>
121 T& makeRefFromPointer(T* ptr)
122 {
123     GMX_ASSERT(ptr != nullptr, "got null pointer");
124     return *ptr;
125 }
126
127 /*! \libinternal \brief
128  * Helper struct bundling the output data of a force provider
129  *
130  * Same as for the ForceProviderInput class, but these variables can be written as well.
131  */
132 class ForceProviderOutput
133 {
134 public:
135     /*! \brief Constructor assembles all necessary force provider output data
136      *
137      * \param[in,out]  forceWithVirial  Container for force and virial
138      * \param[in,out]  enerd            Structure containing energy data
139      */
140     ForceProviderOutput(ForceWithVirial* forceWithVirial, gmx_enerdata_t* enerd) :
141         forceWithVirial_(makeRefFromPointer(forceWithVirial)),
142         enerd_(makeRefFromPointer(enerd))
143     {
144     }
145
146     ForceWithVirial& forceWithVirial_; //!< Container for force and virial
147     gmx_enerdata_t&  enerd_;           //!< Structure containing energy data
148 };
149
150
151 /*! \libinternal \brief
152  * Interface for a component that provides forces during MD.
153  *
154  * Modules implementing IMDModule generally implement this internally, and use
155  * IMDModule::initForceProviders() to register their implementation in
156  * ForceProviders.
157  *
158  * The interface most likely requires additional generalization for use in
159  * other modules than the current electric field implementation.
160  *
161  * The forces that are produced by force providers are not taken into account
162  * in the calculation of the virial. When applicable, the provider should
163  * compute its own virial contribution.
164  *
165  * \inlibraryapi
166  * \ingroup module_mdtypes
167  */
168 class IForceProvider
169 {
170 public:
171     /*! \brief
172      * Computes forces.
173      *
174      * \param[in]    forceProviderInput    struct that collects input data for the force providers
175      * \param[in,out] forceProviderOutput   struct that collects output data of the force providers
176      */
177     virtual void calculateForces(const ForceProviderInput& forceProviderInput,
178                                  ForceProviderOutput*      forceProviderOutput) = 0;
179
180 protected:
181     ~IForceProvider() {}
182 };
183
184 /*! \libinternal \brief
185  * Evaluates forces from a collection of gmx::IForceProvider.
186  *
187  * \inlibraryapi
188  * \ingroup module_mdtypes
189  */
190 class ForceProviders
191 {
192 public:
193     ForceProviders();
194     ~ForceProviders();
195
196     /*! \brief
197      * Adds a provider.
198      */
199     void addForceProvider(gmx::IForceProvider* provider);
200
201     //! Whether there are modules added.
202     bool hasForceProvider() const;
203
204     //! Computes forces.
205     void calculateForces(const gmx::ForceProviderInput& forceProviderInput,
206                          gmx::ForceProviderOutput*      forceProviderOutput) const;
207
208 private:
209     class Impl;
210
211     std::unique_ptr<Impl> impl_;
212 };
213
214 } // namespace gmx
215
216 #endif