2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 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.
37 * Implements nblib Molecule
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>
48 #ifndef NBLIB_MOLECULES_H
49 #define NBLIB_MOLECULES_H
53 #include <unordered_map>
56 #include "nblib/listed_forces/definitions.h"
57 #include "nblib/particletype.h"
61 class TopologyBuilder;
63 //! Named type for unique identifier for a particle in a molecule
64 using ParticleName = StrongType<std::string, struct ParticleNameParameter>;
66 //! Named type for charges on a particle within a molecule
67 using Charge = StrongType<real, struct ChargeParameter>;
69 //! Named type for residue name used to diffentiate between sections of a molecule
70 using ResidueName = StrongType<std::string, struct ResidueNameParameter>;
72 //! Named type for the name of a molecule
73 using MoleculeName = StrongType<std::string, struct MoleculeNameParameter>;
77 std::string particleName_;
78 std::string residueName_;
79 std::string particleTypeName_;
83 //! \brief uniquely identifies a particle within a Molecule
84 class ParticleIdentifier final
87 //! \brief construct form a ParticleName, allow implicit conversion
88 ParticleIdentifier(ParticleName particleName) :
89 particleName_(std::move(particleName)), residueName_()
93 //! \brief construct with a non-default ResidueName
94 ParticleIdentifier(ParticleName particleName, ResidueName residueName) :
95 particleName_(std::move(particleName)), residueName_(std::move(residueName))
99 [[nodiscard]] const ParticleName& particleName() const { return particleName_; }
100 [[nodiscard]] const ResidueName& residueName() const { return residueName_; }
103 ParticleName particleName_;
104 ResidueName residueName_;
106 friend inline bool operator==(const ParticleIdentifier& lhs, const ParticleIdentifier& rhs)
108 return lhs.particleName_ == rhs.particleName_ && lhs.residueName_ == rhs.residueName_;
112 //! \brief Molecule class that holds particles and their bonded interactions
115 //! \brief per-InteractionType storage container for listed interaction with string-based particle IDs
116 template<class InteractionType>
117 struct InteractionTypeData
119 using type = InteractionType;
120 using IdentifierType = Repeat<TypeList<ParticleName, ResidueName>, NCenter<InteractionType>{}>;
122 std::vector<InteractionType> interactionTypes_;
123 std::vector<Reduce<std::tuple, IdentifierType>> interactions_;
126 //! this creates a tuple containing an instance of InteractionType data for each supported listed type
127 using InteractionTuple = Reduce<std::tuple, Map<InteractionTypeData, SupportedListedTypes>>;
129 //! \brief returns the default residue name if necessary
130 ResidueName residueName(const ParticleIdentifier& particleIdentifier);
132 //! \brief adds an interaction to the InteractionTuple
133 template<class ListedVariant, class... ParticleIdentifiers>
134 void addInteractionImpl(const ListedVariant& interaction, const ParticleIdentifiers&... particles);
137 explicit Molecule(MoleculeName moleculeName);
139 //! Add a particle to the molecule with full specification of parameters.
140 Molecule& addParticle(const ParticleName& particleName,
141 const ResidueName& residueName,
142 const Charge& charge,
143 ParticleType const& particleType);
145 //! Add a particle to the molecule with implicit charge of 0
146 Molecule& addParticle(const ParticleName& particleName,
147 const ResidueName& residueName,
148 ParticleType const& particleType);
150 //! \brief Add a particle to the molecule with residueName set using particleName
151 Molecule& addParticle(const ParticleName& particleName, const Charge& charge, ParticleType const& particleType);
153 //! \brief Add a particle to the molecule with residueName set using particleName with implicit charge of 0
154 Molecule& addParticle(const ParticleName& particleName, const ParticleType& particleType);
156 /*! \brief Specify an exclusion between two particles that have been added to the molecule
158 * Exclusion of a particle with itself is detected and handled correctly.
159 * Note that adding an exclusion between particles not present in the Molecule will \throw an
162 void addExclusion(const ParticleIdentifier& particle, const ParticleIdentifier& particleToExclude);
164 /*! \brief Add 2-particle interactions such as harmonic bonds
166 * Note that adding an interaction between particles not present in the Molecule will \throw an
169 void addInteraction(const ParticleIdentifier& particleI,
170 const ParticleIdentifier& particleJ,
171 const TwoCenterInteraction& interaction);
173 //! \brief Add 3-particle interactions such as angles
174 void addInteraction(const ParticleIdentifier& particleI,
175 const ParticleIdentifier& particleJ,
176 const ParticleIdentifier& particleK,
177 const ThreeCenterInteraction& interaction);
179 //! \brief Add 4-particle interactions such as (im)proper-dihedrals
180 void addInteraction(const ParticleIdentifier& particleI,
181 const ParticleIdentifier& particleJ,
182 const ParticleIdentifier& particleK,
183 const ParticleIdentifier& particleL,
184 const FourCenterInteraction& interaction);
186 //! \brief Add 5-particle interactions such as CMAP
187 void addInteraction(const ParticleIdentifier& particleI,
188 const ParticleIdentifier& particleJ,
189 const ParticleIdentifier& particleK,
190 const ParticleIdentifier& particleL,
191 const ParticleIdentifier& particleM,
192 const FiveCenterInteraction& interaction);
194 //! \brief The number of molecules
195 int numParticlesInMolecule() const;
197 //! \brief Return the ParticleType data for a specific particle name that has been added to the molecule
198 const ParticleType& at(const std::string& particlesTypeName) const;
200 /*! \brief access integer-based exclusions
202 * Convert exclusions given by name to indices and unify with exclusions given by indices
203 * returns a sorted vector containing no duplicates of particles to exclude by indices
205 std::vector<std::tuple<int, int>> getExclusions() const;
207 //! \brief Return all interactions stored in Molecule
208 const InteractionTuple& interactionData() const;
210 //! \brief Return name of i-th particle
211 ParticleName particleName(int i) const;
213 //! \brief Return name of i-th residue
214 ResidueName residueName(int i) const;
216 //! \brief Return array of data structs on particle types
217 std::vector<ParticleData> particleData() const;
219 //! \brief Return map of particle types and their names
220 std::unordered_map<std::string, ParticleType> particleTypesMap() const;
222 //! \brief The molecule name
223 MoleculeName name() const;
226 //! Name of the molecule
229 //! one entry per particle in molecule
230 std::vector<ParticleData> particles_;
232 //! collection of distinct particle types in molecule
233 std::unordered_map<std::string, ParticleType> particleTypes_;
235 //! Used for calculated exclusions based on particle indices in molecule
236 std::vector<std::tuple<int, int>> exclusions_;
238 //! we cannot efficiently compute indices during the build-phase
239 //! so we delay the conversion until TopologyBuilder requests it
240 std::vector<std::tuple<std::string, std::string, std::string, std::string>> exclusionsByName_;
242 //! collection of data for all types of interactions
243 InteractionTuple interactionData_;
247 #endif // NBLIB_MOLECULES_H