*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2011,2014,2015,2016,2018, by the GROMACS development team, led by
+ * Copyright (c) 2011,2014,2015,2016,2018, The GROMACS development team.
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/math/vectypes.h"
#include "gromacs/topology/atoms.h"
#include "gromacs/topology/block.h"
+#include "gromacs/topology/forcefieldparameters.h"
#include "gromacs/topology/idef.h"
#include "gromacs/topology/symtab.h"
+#include "gromacs/utility/enumerationhelpers.h"
+#include "gromacs/utility/listoflists.h"
+#include "gromacs/utility/unique_cptr.h"
-enum {
- egcTC, egcENER, egcACC, egcFREEZE,
- egcUser1, egcUser2, egcVCM, egcCompressedX,
- egcORFIT, egcQMMM,
- egcNR
+enum class SimulationAtomGroupType : int
+{
+ TemperatureCoupling,
+ EnergyOutput,
+ Acceleration,
+ Freeze,
+ User1,
+ User2,
+ MassCenterVelocityRemoval,
+ CompressedPositionOutput,
+ OrientationRestraintsFit,
+ QuantumMechanics,
+ Count
};
-/* Names corresponding to groups */
-extern const char *gtypes[egcNR+1];
+
+//! Short strings used for describing atom groups in log and energy files
+const char* shortName(SimulationAtomGroupType type);
+
+// const char *shortName(int type); // if necessary
/*! \brief Molecules type data: atoms, interactions and exclusions */
struct gmx_moltype_t
{
- /*! \brief Constructor */
gmx_moltype_t();
- /*! \brief Destructor */
~gmx_moltype_t();
/*! \brief Deleted copy assignment operator to avoid (not) freeing pointers */
- gmx_moltype_t &operator=(const gmx_moltype_t &) = delete;
+ gmx_moltype_t& operator=(const gmx_moltype_t&) = delete;
/*! \brief Default copy constructor */
- gmx_moltype_t(const gmx_moltype_t &) = default;
+ gmx_moltype_t(const gmx_moltype_t&) = default;
- char **name; /**< Name of the molecule type */
- t_atoms atoms; /**< The atoms in this molecule */
- t_ilist ilist[F_NRE]; /**< Interaction list with local indices */
- t_block cgs; /**< The charge groups */
- t_blocka excls; /**< The exclusions */
+ char** name; /**< Name of the molecule type */
+ t_atoms atoms; /**< The atoms in this molecule */
+ InteractionLists ilist; /**< Interaction list with local indices */
+ gmx::ListOfLists<int> excls; /**< The exclusions */
};
/*! \brief Block of molecules of the same type, used in gmx_mtop_t */
/*! \brief Indices for a gmx_molblock_t, derived from other gmx_mtop_t contents */
struct MoleculeBlockIndices
{
- int numAtomsPerMolecule; /**< Number of atoms in a molecule in the block */
- int globalAtomStart; /**< Global atom index of the first atom in the block */
- int globalAtomEnd; /**< Global atom index + 1 of the last atom in the block */
- int globalResidueStart; /**< Global residue index of the first residue in the block */
- int residueNumberStart; /**< Residue numbers start from this value if the number of residues per molecule is <= maxres_renum */
- int moleculeIndexStart; /**< Global molecule indexing starts from this value */
+ int numAtomsPerMolecule; /**< Number of atoms in a molecule in the block */
+ int globalAtomStart; /**< Global atom index of the first atom in the block */
+ int globalAtomEnd; /**< Global atom index + 1 of the last atom in the block */
+ int globalResidueStart; /**< Global residue index of the first residue in the block */
+ int residueNumberStart; /**< Residue numbers start from this value if the number of residues per molecule is <= maxres_renum */
+ int moleculeIndexStart; /**< Global molecule indexing starts from this value */
};
-typedef struct gmx_groups_t
+/*! \brief Contains the simulation atom groups.
+ *
+ * Organized as containers for the different
+ * SimulationAtomGroupTypes
+ */
+struct SimulationGroups
{
- t_grps grps[egcNR]; /* Groups of things */
- int ngrpname; /* Number of groupnames */
- char ***grpname; /* Names of the groups */
- int ngrpnr[egcNR];
- unsigned char *grpnr[egcNR]; /* Group numbers or NULL */
-} gmx_groups_t;
-
-/* This macro gives the group number of group type egc for atom i.
- * This macro is useful, since the grpnr pointers are NULL
- * for group types that have all entries 0.
+ // TODO: collect groups and groupNumbers in a struct for each group type
+ //! Group numbers for each of the different SimulationAtomGroupType groups.
+ gmx::EnumerationArray<SimulationAtomGroupType, AtomGroupIndices> groups;
+ //! Names of groups, stored as pointer to the entries in the symbol table.
+ std::vector<char**> groupNames;
+ //! Indices into groups for each atom for each of the different SimulationAtomGroupType groups.
+ gmx::EnumerationArray<SimulationAtomGroupType, std::vector<unsigned char>> groupNumbers;
+
+ /*! \brief
+ * Number of atoms for which group numbers are stored for a single SimulationGroup.
+ *
+ * \param[in] group The group type.
+ */
+ int numberOfGroupNumbers(SimulationAtomGroupType group) const
+ {
+ return static_cast<int>(groupNumbers[group].size());
+ }
+};
+
+/*! \brief
+ * Returns group number of an input group for a given atom.
+ *
+ * Returns the group \p type for \p atom in \p group, or 0 if the
+ * entries for all atoms in the group are 0 and the pointer is thus null.
+ *
+ * \param[in] group Group to check.
+ * \param[in] type Type of group to check.
+ * \param[in] atom Atom to check if it has an entry.
*/
-#define ggrpnr(groups, egc, i) ((groups)->grpnr[egc] ? (groups)->grpnr[egc][i] : 0)
+int getGroupType(const SimulationGroups& group, SimulationAtomGroupType type, int atom);
/* The global, complete system topology struct, based on molecule types.
* This structure should contain no data that is O(natoms) in memory.
* TODO: Find a solution for ensuring that the derived data is in sync
* with the primary data, possibly by converting to a class.
*/
-struct gmx_mtop_t
+struct gmx_mtop_t //NOLINT(clang-analyzer-optin.performance.Padding)
{
- /* Constructor */
gmx_mtop_t();
- /* Destructor */
~gmx_mtop_t();
- char **name; /* Name of the topology */
- gmx_ffparams_t ffparams;
- std::vector<gmx_moltype_t> moltype;
+ //! Name of the topology.
+ char** name = nullptr;
+ //! Force field parameters used.
+ gmx_ffparams_t ffparams;
+ //! Vector of different molecule types.
+ std::vector<gmx_moltype_t> moltype;
+ //! Vector of different molecule blocks.
std::vector<gmx_molblock_t> molblock;
- gmx_bool bIntermolecularInteractions; /* Are there intermolecular
- * interactions? */
- t_ilist *intermolecular_ilist; /* List of intermolecular interactions
- * using system wide atom indices,
- * either NULL or size F_NRE */
- int natoms;
- int maxres_renum; /* Parameter for residue numbering */
- int maxresnr; /* The maximum residue number in moltype */
- t_atomtypes atomtypes; /* Atomtype properties */
- gmx_groups_t groups; /* Groups of atoms for different purposes */
- t_symtab symtab; /* The symbol table */
- bool haveMoleculeIndices; /* Tells whether we have valid molecule indices */
-
- /* Derived data */
- std::vector<MoleculeBlockIndices> moleculeBlockIndices; /* Indices for each molblock entry for fast lookup of atom properties */
+ //! Are there intermolecular interactions?
+ bool bIntermolecularInteractions = false;
+ /* \brief
+ * List of intermolecular interactions using system wide
+ * atom indices, either NULL or size F_NRE
+ */
+ std::unique_ptr<InteractionLists> intermolecular_ilist = nullptr;
+ //! Number of global atoms.
+ int natoms = 0;
+ //! Atomtype properties
+ t_atomtypes atomtypes;
+ //! Groups of atoms for different purposes
+ SimulationGroups groups;
+ //! The legacy symbol table
+ t_symtab symtab;
+ //! Tells whether we have valid molecule indices
+ bool haveMoleculeIndices = false;
+ /*! \brief List of global atom indices of atoms between which
+ * non-bonded interactions must be excluded.
+ */
+ std::vector<int> intermolecularExclusionGroup;
+
+ //! Maximum number of residues in molecule to trigger renumbering of residues
+ int maxResiduesPerMoleculeToTriggerRenumber() const
+ {
+ return maxResiduesPerMoleculeToTriggerRenumber_;
+ }
+ //! Maximum residue number that is not renumbered.
+ int maxResNumberNotRenumbered() const { return maxResNumberNotRenumbered_; }
+ /*! \brief Finalize this data structure.
+ *
+ * Should be called after generating or reading mtop, to set some compute
+ * intesive variables to avoid N^2 operations later on.
+ *
+ * \todo Move into a builder class, once available.
+ */
+ void finalize();
+
+ /* Derived data below */
+ //! Indices for each molblock entry for fast lookup of atom properties
+ std::vector<MoleculeBlockIndices> moleculeBlockIndices;
+
+private:
+ //! Build the molblock indices
+ void buildMolblockIndices();
+ //! Maximum number of residues in molecule to trigger renumbering of residues
+ int maxResiduesPerMoleculeToTriggerRenumber_ = 0;
+ //! The maximum residue number in moltype that is not renumbered
+ int maxResNumberNotRenumbered_ = -1;
};
-/* The mdrun node-local topology struct, completely written out */
-typedef struct gmx_localtop_t
+/*! \brief
+ * The fully written out topology for a domain over its lifetime
+ *
+ * Also used in some analysis code.
+ */
+struct gmx_localtop_t
{
- t_idef idef; /* The interaction function definition */
- t_atomtypes atomtypes; /* Atomtype properties */
- t_block cgs; /* The charge groups */
- t_blocka excls; /* The exclusions */
-} gmx_localtop_t;
+ //! Constructor used for normal operation, manages own resources.
+ gmx_localtop_t(const gmx_ffparams_t& ffparams);
+
+ //! The interaction function definition
+ InteractionDefinitions idef;
+ //! The exclusions
+ gmx::ListOfLists<int> excls;
+};
/* The old topology struct, completely written out, used in analysis tools */
typedef struct t_topology
{
- char **name; /* Name of the topology */
- t_idef idef; /* The interaction function definition */
- t_atoms atoms; /* The atoms */
- t_atomtypes atomtypes; /* Atomtype properties */
- t_block cgs; /* The charge groups */
- t_block mols; /* The molecules */
- gmx_bool bIntermolecularInteractions; /* Inter.mol. int. ? */
- t_blocka excls; /* The exclusions */
- t_symtab symtab; /* The symbol table */
+ char** name; /* Name of the topology */
+ t_idef idef; /* The interaction function definition */
+ t_atoms atoms; /* The atoms */
+ t_atomtypes atomtypes; /* Atomtype properties */
+ t_block mols; /* The molecules */
+ gmx_bool bIntermolecularInteractions; /* Inter.mol. int. ? */
+ /* Note that the exclusions are not stored in t_topology */
+ t_symtab symtab; /* The symbol table */
} t_topology;
-void init_mtop(gmx_mtop_t *mtop);
-void init_top(t_topology *top);
-void done_gmx_groups_t(gmx_groups_t *g);
-void done_top(t_topology *top);
+void init_top(t_topology* top);
+void done_top(t_topology* top);
// Frees both t_topology and gmx_mtop_t when the former has been created from
// the latter.
-void done_top_mtop(t_topology *top, gmx_mtop_t *mtop);
+void done_top_mtop(t_topology* top, gmx_mtop_t* mtop);
+
+bool gmx_mtop_has_masses(const gmx_mtop_t* mtop);
+bool gmx_mtop_has_charges(const gmx_mtop_t* mtop);
+bool gmx_mtop_has_perturbed_charges(const gmx_mtop_t& mtop);
+bool gmx_mtop_has_atomtypes(const gmx_mtop_t* mtop);
+bool gmx_mtop_has_pdbinfo(const gmx_mtop_t* mtop);
-bool gmx_mtop_has_masses(const gmx_mtop_t *mtop);
-bool gmx_mtop_has_charges(const gmx_mtop_t *mtop);
-bool gmx_mtop_has_atomtypes(const gmx_mtop_t *mtop);
-bool gmx_mtop_has_pdbinfo(const gmx_mtop_t *mtop);
+void pr_mtop(FILE* fp, int indent, const char* title, const gmx_mtop_t* mtop, gmx_bool bShowNumbers, gmx_bool bShowParameters);
+void pr_top(FILE* fp, int indent, const char* title, const t_topology* top, gmx_bool bShowNumbers, gmx_bool bShowParameters);
+
+/*! \brief Compare two mtop topologies.
+ *
+ * \param[in] fp File pointer to write to.
+ * \param[in] mtop1 First topology to compare.
+ * \param[in] mtop2 Second topology to compare.
+ * \param[in] relativeTolerance Relative tolerance for comparison.
+ * \param[in] absoluteTolerance Absolute tolerance for comparison.
+ */
+void compareMtop(FILE* fp, const gmx_mtop_t& mtop1, const gmx_mtop_t& mtop2, real relativeTolerance, real absoluteTolerance);
+
+/*! \brief Check perturbation parameters in topology.
+ *
+ * \param[in] fp File pointer to write to.
+ * \param[in] mtop1 Topology to check perturbation parameters in.
+ * \param[in] relativeTolerance Relative tolerance for comparison.
+ * \param[in] absoluteTolerance Absolute tolerance for comparison.
+ */
+void compareMtopAB(FILE* fp, const gmx_mtop_t& mtop1, real relativeTolerance, real absoluteTolerance);
+
+/*! \brief Compare groups.
+ *
+ * \param[in] fp File pointer to write to.
+ * \param[in] g0 First group for comparison.
+ * \param[in] g1 Second group for comparison.
+ * \param[in] natoms0 Number of atoms for first group.
+ * \param[in] natoms1 Number of atoms for second group.
+ */
+void compareAtomGroups(FILE* fp, const SimulationGroups& g0, const SimulationGroups& g1, int natoms0, int natoms1);
-void pr_mtop(FILE *fp, int indent, const char *title, const gmx_mtop_t *mtop,
- gmx_bool bShowNumbers, gmx_bool bShowParameters);
-void pr_top(FILE *fp, int indent, const char *title, const t_topology *top,
- gmx_bool bShowNumbers, gmx_bool bShowParameters);
+//! Typedef for gmx_localtop in analysis tools.
+using ExpandedTopologyPtr = std::unique_ptr<gmx_localtop_t>;
-void cmp_top(FILE *fp, const t_topology *t1, const t_topology *t2, real ftol, real abstol);
-void cmp_groups(FILE *fp, const gmx_groups_t *g0, const gmx_groups_t *g1,
- int natoms0, int natoms1);
+void copy_moltype(const gmx_moltype_t* src, gmx_moltype_t* dst);
#endif