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)),
94 //! \brief construct with a non-default ResidueName
95 ParticleIdentifier(ParticleName particleName, ResidueName residueName) :
96 particleName_(std::move(particleName)),
97 residueName_(std::move(residueName))
101 [[nodiscard]] const ParticleName& particleName() const { return particleName_; }
102 [[nodiscard]] const ResidueName& residueName() const { return residueName_; }
105 ParticleName particleName_;
106 ResidueName residueName_;
108 friend inline bool operator==(const ParticleIdentifier& lhs, const ParticleIdentifier& rhs)
110 return lhs.particleName_ == rhs.particleName_ && lhs.residueName_ == rhs.residueName_;
114 //! \brief Molecule class that holds particles and their bonded interactions
117 //! \brief per-InteractionType storage container for listed interaction with string-based particle IDs
118 template<class InteractionType>
119 struct InteractionTypeData
121 using type = InteractionType;
122 using IdentifierType = Repeat<TypeList<ParticleName, ResidueName>, NCenter<InteractionType>{}>;
124 std::vector<InteractionType> interactionTypes_;
125 std::vector<Reduce<std::tuple, IdentifierType>> interactions_;
128 //! this creates a tuple containing an instance of InteractionType data for each supported listed type
129 using InteractionTuple = Reduce<std::tuple, Map<InteractionTypeData, SupportedListedTypes>>;
131 //! \brief returns the default residue name if necessary
132 ResidueName residueName(const ParticleIdentifier& particleIdentifier);
134 //! \brief adds an interaction to the InteractionTuple
135 template<class ListedVariant, class... ParticleIdentifiers>
136 void addInteractionImpl(const ListedVariant& interaction, const ParticleIdentifiers&... particles);
139 explicit Molecule(MoleculeName moleculeName);
141 //! Add a particle to the molecule with full specification of parameters.
142 Molecule& addParticle(const ParticleName& particleName,
143 const ResidueName& residueName,
144 const Charge& charge,
145 ParticleType const& particleType);
147 //! Add a particle to the molecule with implicit charge of 0
148 Molecule& addParticle(const ParticleName& particleName,
149 const ResidueName& residueName,
150 ParticleType const& particleType);
152 //! \brief Add a particle to the molecule with residueName set using particleName
153 Molecule& addParticle(const ParticleName& particleName, const Charge& charge, ParticleType const& particleType);
155 //! \brief Add a particle to the molecule with residueName set using particleName with implicit charge of 0
156 Molecule& addParticle(const ParticleName& particleName, const ParticleType& particleType);
158 /*! \brief Specify an exclusion between two particles that have been added to the molecule
160 * Exclusion of a particle with itself is detected and handled correctly.
161 * Note that adding an exclusion between particles not present in the Molecule will \throw an
164 void addExclusion(const ParticleIdentifier& particle, const ParticleIdentifier& particleToExclude);
166 /*! \brief Add 2-particle interactions such as harmonic bonds
168 * Note that adding an interaction between particles not present in the Molecule will \throw an
171 void addInteraction(const ParticleIdentifier& particleI,
172 const ParticleIdentifier& particleJ,
173 const TwoCenterInteraction& interaction);
175 //! \brief Add 3-particle interactions such as angles
176 void addInteraction(const ParticleIdentifier& particleI,
177 const ParticleIdentifier& particleJ,
178 const ParticleIdentifier& particleK,
179 const ThreeCenterInteraction& interaction);
181 //! \brief Add 4-particle interactions such as (im)proper-dihedrals
182 void addInteraction(const ParticleIdentifier& particleI,
183 const ParticleIdentifier& particleJ,
184 const ParticleIdentifier& particleK,
185 const ParticleIdentifier& particleL,
186 const FourCenterInteraction& interaction);
188 //! \brief Add 5-particle interactions such as CMAP
189 void addInteraction(const ParticleIdentifier& particleI,
190 const ParticleIdentifier& particleJ,
191 const ParticleIdentifier& particleK,
192 const ParticleIdentifier& particleL,
193 const ParticleIdentifier& particleM,
194 const FiveCenterInteraction& interaction);
196 //! \brief The number of molecules
197 int numParticlesInMolecule() const;
199 //! \brief Return the ParticleType data for a specific particle name that has been added to the molecule
200 const ParticleType& at(const std::string& particlesTypeName) const;
202 /*! \brief access integer-based exclusions
204 * Convert exclusions given by name to indices and unify with exclusions given by indices
205 * returns a sorted vector containing no duplicates of particles to exclude by indices
207 std::vector<std::tuple<int, int>> getExclusions() const;
209 //! \brief Return all interactions stored in Molecule
210 const InteractionTuple& interactionData() const;
212 //! \brief Return name of i-th particle
213 ParticleName particleName(int i) const;
215 //! \brief Return name of i-th residue
216 ResidueName residueName(int i) const;
218 //! \brief Return array of data structs on particle types
219 std::vector<ParticleData> particleData() const;
221 //! \brief Return map of particle types and their names
222 std::unordered_map<std::string, ParticleType> particleTypesMap() const;
224 //! \brief The molecule name
225 MoleculeName name() const;
228 //! Name of the molecule
231 //! one entry per particle in molecule
232 std::vector<ParticleData> particles_;
234 //! collection of distinct particle types in molecule
235 std::unordered_map<std::string, ParticleType> particleTypes_;
237 //! Used for calculated exclusions based on particle indices in molecule
238 std::vector<std::tuple<int, int>> exclusions_;
240 //! we cannot efficiently compute indices during the build-phase
241 //! so we delay the conversion until TopologyBuilder requests it
242 std::vector<std::tuple<std::string, std::string, std::string, std::string>> exclusionsByName_;
244 //! collection of data for all types of interactions
245 InteractionTuple interactionData_;
249 #endif // NBLIB_MOLECULES_H