NBLIB listed forces API update
[alexxy/gromacs.git] / api / nblib / listed_forces / definitions.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2020, 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 /*! \inpublicapi \file
36  * \brief
37  * Definitions for supported nblib listed interaction data, such as bonds, angles, dihedrals, etc
38  *
39  * \author Victor Holanda <victor.holanda@cscs.ch>
40  * \author Joe Jordan <ejjordan@kth.se>
41  * \author Prashanth Kanduri <kanduri@cscs.ch>
42  * \author Sebastian Keller <keller@cscs.ch>
43  * \author Artem Zhmurov <zhmurov@gmail.com>
44  *
45  * A note on the preprocessor (PP) usage in this file:
46  *
47  * The PP macros defined here are used exclusively to generate
48  * template instantiations declarations of the form "extern template function(X)"
49  * in header files and "template function(X)" in .cpp files.
50  * These declarations do not affect the program logic in any way and neither are they
51  * required to read and understand the behavior of the code as they do not
52  * result in any executable instructions.
53  * In fact, it would even be technically possible to omit these PP generated
54  * declarations in the header files and replace them with an unused static function
55  * in the .cpp file that calls the template function in question
56  * (e.g. Molecule::addInteraction) once with each type from the variadic template
57  * TypeLists declared in this file. This would be enough to create the required instantiations.
58  * It would, however, create more work for the compiler which then has to instantiate the
59  * templates in the header in each translation unit where the header is included.
60  * Doing this results in a compiler warning.
61  *
62  */
63 #ifndef NBLIB_LISTEDFORCES_DEFINITIONS_H
64 #define NBLIB_LISTEDFORCES_DEFINITIONS_H
65
66 #include "nblib/util/user.h"
67 #include "bondtypes.h"
68
69 namespace nblib
70 {
71
72 //***********************************************************************************
73
74 /*! \brief These macros define what interaction types are supported in
75  *  -Molecule
76  *  -Topology
77  *  -ListedForceCalculator
78  *
79  *  To enable force calculation for your new interaction type that you've added to bondtypes.h,
80  *  list your new type here under the appropriate category and make sure that you've added
81  *  a kernel in kernels.hpp
82  */
83
84 #define SUPPORTED_TWO_CENTER_TYPES \
85     HarmonicBondType, G96BondType, CubicBondType, FENEBondType, HalfAttractiveQuarticBondType
86
87 #define SUPPORTED_THREE_CENTER_TYPES DefaultAngle
88
89 #define SUPPORTED_FOUR_CENTER_TYPES ProperDihedral, ImproperDihedral, RyckaertBellemanDihedral
90
91 #define SUPPORTED_FIVE_CENTER_TYPES Default5Center
92
93 //***********************************************************************************
94
95 #define SUPPORTED_LISTED_TYPES                                                             \
96     SUPPORTED_TWO_CENTER_TYPES, SUPPORTED_THREE_CENTER_TYPES, SUPPORTED_FOUR_CENTER_TYPES, \
97             SUPPORTED_FIVE_CENTER_TYPES
98
99 #define NBLIB_ALWAYS_INLINE __attribute((always_inline))
100
101 //! \brief encodes the number of integers needed to represent 2-center interactions (bonds, pairs)
102 using TwoCenterInteractionIndex = std::array<int, 3>;
103 //! \brief encodes the number of integers needed to represent 3-center interactions (angles)
104 using ThreeCenterInteractionIndex = std::array<int, 4>;
105 //! \brief encodes the number of integers needed to represent 4-center interactions (dihedrals)
106 using FourCenterInteractionIndex = std::array<int, 5>;
107 //! \brief encodes the number of integers needed to represent 5-center interactions (CMAP)
108 using FiveCenterInteractionIndex = std::array<int, 6>;
109
110 //! \brief data type for pairwise interactions, e.g. bonds
111 template<class TwoCenterType>
112 struct TwoCenterData
113 {
114     using type = TwoCenterType;
115
116     // tuple format: <particleID i, particleID j, TwoCenterInstanceIndex>
117     std::vector<TwoCenterInteractionIndex> indices;
118     // vector of unique TwoCenterType instances
119     std::vector<TwoCenterType> parameters;
120 };
121
122 //! \brief data type for three-center interactions, e.g. angles
123 template<class ThreeCenterType>
124 struct ThreeCenterData
125 {
126     using type = ThreeCenterType;
127
128     // tuple format: <particleID i, particleID j, particleID k, ThreeCenterInstanceIndex>
129     std::vector<ThreeCenterInteractionIndex> indices;
130     // vector of unique ThreeCenterType instances
131     std::vector<ThreeCenterType> parameters;
132 };
133
134 //! \brief data type for four-center interactions, e.g. dihedrals
135 template<class FourCenterType>
136 struct FourCenterData
137 {
138     using type = FourCenterType;
139
140     // tuple format: <particleID i, particleID j, particleID k, particleID l, FourCenterInstanceIndex>
141     std::vector<FourCenterInteractionIndex> indices;
142     // vector of unique FiveCenterType instances
143     std::vector<FourCenterType> parameters;
144 };
145
146 //! \brief data type for five-center interactions, e.g. CMAP
147 template<class FiveCenterType>
148 struct FiveCenterData
149 {
150     using type = FiveCenterType;
151
152     // tuple format: <particleID i, particleID j, particleID k, particleID l, particleID m, FiveCenterInstanceIndex>
153     std::vector<FiveCenterInteractionIndex> indices;
154     // vector of unique FiveCenterType instances
155     std::vector<FiveCenterType> parameters;
156 };
157
158
159 using SupportedTwoCenterTypes = TypeList<SUPPORTED_TWO_CENTER_TYPES>;
160 // std::tuple<TwoCenterData<TwoCenterType1>, ...>
161 using TwoCenterInteractionData = Reduce<std::tuple, Map<TwoCenterData, SupportedTwoCenterTypes>>;
162
163 using SupportedThreeCenterTypes = TypeList<SUPPORTED_THREE_CENTER_TYPES>;
164 // std::tuple<AngleData<ThreeCenterType1>, ...>
165 using ThreeCenterInteractionData = Reduce<std::tuple, Map<ThreeCenterData, SupportedThreeCenterTypes>>;
166
167 using SupportedFourCenterTypes = TypeList<SUPPORTED_FOUR_CENTER_TYPES>;
168 // std::tuple<FourCenterData<FourCenterType1>, ...>
169 using FourCenterInteractionData = Reduce<std::tuple, Map<FourCenterData, SupportedFourCenterTypes>>;
170
171 using SupportedFiveCenterTypes = TypeList<SUPPORTED_FIVE_CENTER_TYPES>;
172 // std::tuple<FiveCenterData<FiveCenterType1>, ...>
173 using FiveCenterInteractionData = Reduce<std::tuple, Map<FiveCenterData, SupportedFiveCenterTypes>>;
174
175 //! This is the complete type that holds all listed interaction data
176 using ListedInteractionData = decltype(std::tuple_cat(TwoCenterInteractionData{},
177                                                       ThreeCenterInteractionData{},
178                                                       FourCenterInteractionData{},
179                                                       FiveCenterInteractionData{}));
180 } // namespace nblib
181 #endif // NBLIB_LISTEDFORCES_DEFINITIONS_H