Refactor gmx_group_t to SimulationAtomGroups
authorPaul Bauer <paul.bauer.q@gmail.com>
Thu, 14 Mar 2019 11:21:55 +0000 (12:21 +0100)
committerMark Abraham <mark.j.abraham@gmail.com>
Tue, 2 Apr 2019 13:19:07 +0000 (15:19 +0200)
Change allocation on type to std::container, but did not touch to
underlying t_grps datastructure yet.

Change-Id: I3858e650a31764b3ab83090eaa0653fc579a8af1

45 files changed:
src/gromacs/fileio/enxio.cpp
src/gromacs/fileio/enxio.h
src/gromacs/fileio/tngio.cpp
src/gromacs/fileio/tpxio.cpp
src/gromacs/gmxpreprocess/grompp.cpp
src/gromacs/gmxpreprocess/readir.cpp
src/gromacs/gmxpreprocess/readir.h
src/gromacs/gmxpreprocess/topio.cpp
src/gromacs/listed_forces/orires.cpp
src/gromacs/mdlib/broadcaststructs.cpp
src/gromacs/mdlib/compute_io.cpp
src/gromacs/mdlib/compute_io.h
src/gromacs/mdlib/energyoutput.cpp
src/gromacs/mdlib/energyoutput.h
src/gromacs/mdlib/force.cpp
src/gromacs/mdlib/force.h
src/gromacs/mdlib/forcerec.cpp
src/gromacs/mdlib/mdatoms.cpp
src/gromacs/mdlib/mdoutf.cpp
src/gromacs/mdlib/membed.cpp
src/gromacs/mdlib/ns.cpp
src/gromacs/mdlib/ns.h
src/gromacs/mdlib/qmmm.cpp
src/gromacs/mdlib/shellfc.cpp
src/gromacs/mdlib/shellfc.h
src/gromacs/mdlib/sim_util.cpp
src/gromacs/mdlib/tgroup.cpp
src/gromacs/mdlib/update.cpp
src/gromacs/mdlib/vcm.cpp
src/gromacs/mdlib/vcm.h
src/gromacs/mdlib/wall.cpp
src/gromacs/mdlib/wall.h
src/gromacs/mdrun/md.cpp
src/gromacs/mdrun/mimic.cpp
src/gromacs/mdrun/minimize.cpp
src/gromacs/mdrun/rerun.cpp
src/gromacs/mdrun/runner.cpp
src/gromacs/mdrun/tpi.cpp
src/gromacs/mimic/utilities.cpp
src/gromacs/pulling/pull.cpp
src/gromacs/tools/dump.cpp
src/gromacs/topology/topology.cpp
src/gromacs/topology/topology.h
src/gromacs/utility/CMakeLists.txt
src/gromacs/utility/enumerationhelpers.h

index cc2ac96df42e1ee83055f6919b95962391323f0d..35be6cb9e034e6866039798c5f95b88bdb83e7a3 100644 (file)
@@ -1149,7 +1149,7 @@ static real find_energy(const char *name, int nre, gmx_enxnm_t *enm,
 }
 
 
-void get_enx_state(const char *fn, real t, const gmx_groups_t *groups, t_inputrec *ir,
+void get_enx_state(const char *fn, real t, const SimulationGroups &groups, t_inputrec *ir,
                    t_state *state)
 {
     /* Should match the names in mdebin.c */
@@ -1208,8 +1208,8 @@ void get_enx_state(const char *fn, real t, const gmx_groups_t *groups, t_inputre
 
         for (i = 0; i < state->ngtc; i++)
         {
-            ni   = groups->grps[egcTC].nm_ind[i];
-            bufi = *(groups->grpname[ni]);
+            ni   = groups.groups[SimulationAtomGroupType::TemperatureCoupling].nm_ind[i];
+            bufi = *(groups.groupNames[ni]);
             for (j = 0; (j < state->nhchainlength); j++)
             {
                 if (inputrecNvtTrotter(ir))
index fa11a2056e0bb1460f39997ca807b7bfd1e9ad38..209bff63981ce11278e261ae8beb6ac22f2034ae 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, 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.
@@ -41,7 +41,7 @@
 #include "gromacs/utility/basedefinitions.h"
 #include "gromacs/utility/real.h"
 
-struct gmx_groups_t;
+struct SimulationGroups;
 struct t_energy;
 struct t_enxframe;
 struct t_fileio;
@@ -176,7 +176,7 @@ gmx_bool do_enx(ener_file_t ef, t_enxframe *fr);
 /* Reads enx_frames, memory in fr is (re)allocated if necessary */
 
 void get_enx_state(const char *fn, real t,
-                   const gmx_groups_t *groups, t_inputrec *ir,
+                   const SimulationGroups &groups, t_inputrec *ir,
                    t_state *state);
 /*
  * Reads state variables from enx file fn at time t.
index d3a7b7d12b3d8251dc9149f3f1f7a77b8f051f3c..c6e29176971e59f38c17deba3071d2cf1e0ba45c 100644 (file)
@@ -572,8 +572,8 @@ void gmx_tng_prepare_md_writing(gmx_tng_trajectory_t  gmx_tng,
 #if GMX_USE_TNG
 /* Check if all atoms in the molecule system are selected
  * by a selection group of type specified by gtype. */
-static gmx_bool all_atoms_selected(const gmx_mtop_t *mtop,
-                                   const int         gtype)
+static gmx_bool all_atoms_selected(const gmx_mtop_t             *mtop,
+                                   const SimulationAtomGroupType gtype)
 {
     /* Iterate through all atoms in the molecule system and
      * check if they belong to a selection group of the
@@ -629,22 +629,22 @@ static void add_selection_groups(gmx_tng_trajectory_t  gmx_tng,
 
     /* If no atoms are selected we do not need to create a
      * TNG selection group molecule. */
-    if (mtop->groups.ngrpnr[egcCompressedX] == 0)
+    if (mtop->groups.numberOfGroupNumbers(SimulationAtomGroupType::CompressedPositionOutput) == 0)
     {
         return;
     }
 
     /* If all atoms are selected we do not have to create a selection
      * group molecule in the TNG molecule system. */
-    if (all_atoms_selected(mtop, egcCompressedX))
+    if (all_atoms_selected(mtop, SimulationAtomGroupType::CompressedPositionOutput))
     {
         return;
     }
 
     /* The name of the TNG molecule containing the selection group is the
      * same as the name of the selection group. */
-    nameIndex = *mtop->groups.grps[egcCompressedX].nm_ind;
-    groupName = *mtop->groups.grpname[nameIndex];
+    nameIndex = *mtop->groups.groups[SimulationAtomGroupType::CompressedPositionOutput].nm_ind;
+    groupName = *mtop->groups.groupNames[nameIndex];
 
     tng_molecule_alloc(tng, &mol);
     tng_molecule_name_set(tng, mol, groupName);
@@ -664,7 +664,7 @@ static void add_selection_groups(gmx_tng_trajectory_t  gmx_tng,
                 char *res_name;
                 int   res_id;
 
-                if (getGroupType(mtop->groups, egcCompressedX, i) != 0)
+                if (getGroupType(mtop->groups, SimulationAtomGroupType::CompressedPositionOutput, i) != 0)
                 {
                     continue;
                 }
@@ -707,8 +707,8 @@ static void add_selection_groups(gmx_tng_trajectory_t  gmx_tng,
                             int atom1, atom2;
                             atom1 = ilist.iatoms[l] + atom_offset;
                             atom2 = ilist.iatoms[l + 1] + atom_offset;
-                            if (getGroupType(mtop->groups, egcCompressedX, atom1) == 0 &&
-                                getGroupType(mtop->groups, egcCompressedX, atom2) == 0)
+                            if (getGroupType(mtop->groups, SimulationAtomGroupType::CompressedPositionOutput, atom1) == 0 &&
+                                getGroupType(mtop->groups, SimulationAtomGroupType::CompressedPositionOutput, atom2) == 0)
                             {
                                 tng_molecule_bond_add(tng, mol, ilist.iatoms[l],
                                                       ilist.iatoms[l + 1], &tngBond);
@@ -724,14 +724,14 @@ static void add_selection_groups(gmx_tng_trajectory_t  gmx_tng,
                     atom1 = ilist.iatoms[l] + atom_offset;
                     atom2 = ilist.iatoms[l + 1] + atom_offset;
                     atom3 = ilist.iatoms[l + 2] + atom_offset;
-                    if (getGroupType(mtop->groups, egcCompressedX, atom1) == 0)
+                    if (getGroupType(mtop->groups, SimulationAtomGroupType::CompressedPositionOutput, atom1) == 0)
                     {
-                        if (getGroupType(mtop->groups, egcCompressedX, atom2) == 0)
+                        if (getGroupType(mtop->groups, SimulationAtomGroupType::CompressedPositionOutput, atom2) == 0)
                         {
                             tng_molecule_bond_add(tng, mol, atom1,
                                                   atom2, &tngBond);
                         }
-                        if (getGroupType(mtop->groups, egcCompressedX, atom3) == 0)
+                        if (getGroupType(mtop->groups, SimulationAtomGroupType::CompressedPositionOutput, atom3) == 0)
                         {
                             tng_molecule_bond_add(tng, mol, atom1,
                                                   atom3, &tngBond);
index fb04ec0ee2801f356e6f106f971f6d754053c813..5e7c77c73bc81322f8180cc79e1878ca9eec7e9e 100644 (file)
@@ -2190,16 +2190,18 @@ static void do_atom(t_fileio *fio, t_atom *atom, gmx_bool bRead)
     }
 }
 
-static void do_grps(t_fileio *fio, int ngrp, t_grps grps[], gmx_bool bRead)
+static void do_grps(t_fileio             *fio,
+                    gmx::ArrayRef<t_grps> grps,
+                    gmx_bool              bRead)
 {
-    for (int j = 0; j < ngrp; j++)
+    for (auto &group : grps)
     {
-        gmx_fio_do_int(fio, grps[j].nr);
+        gmx_fio_do_int(fio, group.nr);
         if (bRead)
         {
-            snew(grps[j].nm_ind, grps[j].nr);
+            snew(group.nm_ind, group.nr);
         }
-        gmx_fio_ndo_int(fio, grps[j].nm_ind, grps[j].nr);
+        gmx_fio_ndo_int(fio, group.nm_ind, group.nr);
     }
 }
 
@@ -2292,35 +2294,28 @@ static void do_atoms(t_fileio *fio, t_atoms *atoms, gmx_bool bRead, t_symtab *sy
     do_resinfo(fio, atoms->nres, atoms->resinfo, bRead, symtab, file_version);
 }
 
-static void do_groups(t_fileio *fio, gmx_groups_t *groups,
+static void do_groups(t_fileio *fio, SimulationGroups *groups,
                       gmx_bool bRead, t_symtab *symtab)
 {
-    int      g;
-
-    do_grps(fio, egcNR, groups->grps, bRead);
-    gmx_fio_do_int(fio, groups->ngrpname);
+    do_grps(fio, groups->groups, bRead);
+    int numberOfGroupNames = groups->groupNames.size();
+    gmx_fio_do_int(fio, numberOfGroupNames);
     if (bRead)
     {
-        snew(groups->grpname, groups->ngrpname);
+        groups->groupNames.resize(numberOfGroupNames);
     }
-    do_strstr(fio, groups->ngrpname, groups->grpname, bRead, symtab);
-    for (g = 0; g < egcNR; g++)
+    do_strstr(fio, numberOfGroupNames, groups->groupNames.data(), bRead, symtab);
+    for (auto group : gmx::keysOf(groups->groupNumbers))
     {
-        gmx_fio_do_int(fio, groups->ngrpnr[g]);
-        if (groups->ngrpnr[g] == 0)
-        {
-            if (bRead)
-            {
-                groups->grpnr[g] = nullptr;
-            }
-        }
-        else
+        int numberOfGroupNumbers = groups->numberOfGroupNumbers(group);
+        gmx_fio_do_int(fio, numberOfGroupNumbers);
+        if (numberOfGroupNumbers != 0)
         {
             if (bRead)
             {
-                snew(groups->grpnr[g], groups->ngrpnr[g]);
+                groups->groupNumbers[group].resize(numberOfGroupNumbers);
             }
-            gmx_fio_ndo_uchar(fio, groups->grpnr[g], groups->ngrpnr[g]);
+            gmx_fio_ndo_uchar(fio, groups->groupNumbers[group].data(), numberOfGroupNumbers);
         }
     }
 }
index 189743bdc13841cec63753137cc35986fd376798..29a466d0dae8b8e0a8b45d69760e36c8ba6e0ba6 100644 (file)
@@ -320,10 +320,10 @@ static void check_eg_vs_cg(gmx_mtop_t *mtop)
             {
                 /* Get the energy group of the first atom in this charge group */
                 firstj  = astart + molt->cgs.index[cg];
-                firsteg = getGroupType(mtop->groups, egcENER, firstj);
+                firsteg = getGroupType(mtop->groups, SimulationAtomGroupType::EnergyOutput, firstj);
                 for (j = molt->cgs.index[cg]+1; j < molt->cgs.index[cg+1]; j++)
                 {
-                    eg = getGroupType(mtop->groups, egcENER, astart+j);
+                    eg = getGroupType(mtop->groups, SimulationAtomGroupType::EnergyOutput, astart+j);
                     if (eg != firsteg)
                     {
                         gmx_fatal(FARGS, "atoms %d and %d in charge group %d of molecule type '%s' are in different energy groups",
@@ -932,7 +932,7 @@ static void cont_status(const char *slog, const char *ener,
 
     if ((ir->epc != epcNO  || ir->etc == etcNOSEHOOVER) && ener)
     {
-        get_enx_state(ener, use_time, &sys->groups, ir, state);
+        get_enx_state(ener, use_time, sys->groups, ir, state);
         preserve_box_shape(ir, state->box_rel, state->boxv);
     }
 }
@@ -2408,7 +2408,7 @@ int gmx_grompp(int argc, char *argv[])
 
     {
         char   warn_buf[STRLEN];
-        double cio = compute_io(ir, sys.natoms, &sys.groups, F_NRE, 1);
+        double cio = compute_io(ir, sys.natoms, sys.groups, F_NRE, 1);
         sprintf(warn_buf, "This run will generate roughly %.0f Mb of data", cio);
         if (cio > 2000)
         {
index 6fd7e16227252611473fe4fb1f146471bb47ba53..2befac6e90f3662f6342f133f1b9f3b079f03429 100644 (file)
@@ -1662,22 +1662,19 @@ static void do_wall_params(t_inputrec *ir,
     }
 }
 
-static void add_wall_energrps(gmx_groups_t *groups, int nwall, t_symtab *symtab)
+static void add_wall_energrps(SimulationGroups *groups, int nwall, t_symtab *symtab)
 {
-    int     i;
-    t_grps *grps;
-    char    str[STRLEN];
-
     if (nwall > 0)
     {
-        srenew(groups->grpname, groups->ngrpname+nwall);
-        grps = &(groups->grps[egcENER]);
+        t_grps *grps = &(groups->groups[SimulationAtomGroupType::EnergyOutput]);
         srenew(grps->nm_ind, grps->nr+nwall);
-        for (i = 0; i < nwall; i++)
+        for (int i = 0; i < nwall; i++)
         {
-            sprintf(str, "wall%d", i);
-            groups->grpname[groups->ngrpname] = put_symtab(symtab, str);
-            grps->nm_ind[grps->nr++]          = groups->ngrpname++;
+            groups->groupNames.emplace_back(
+                    put_symtab(
+                            symtab,
+                            gmx::formatString("wall%d", i).c_str()));
+            grps->nm_ind[grps->nr++] = groups->groupNames.size() - 1;
         }
     }
 }
@@ -2616,21 +2613,21 @@ int search_string(const char *s, int ng, char *gn[])
               s);
 }
 
-static bool do_numbering(int natoms, gmx_groups_t *groups,
+static bool do_numbering(int natoms, SimulationGroups *groups,
                          gmx::ArrayRef<std::string> groupsFromMdpFile,
                          t_blocka *block, char *gnames[],
-                         int gtype, int restnm,
+                         SimulationAtomGroupType gtype, int restnm,
                          int grptp, bool bVerbose,
                          warninp_t wi)
 {
     unsigned short *cbuf;
-    t_grps         *grps = &(groups->grps[gtype]);
+    t_grps         *grps = &(groups->groups[gtype]);
     int             j, gid, aj, ognr, ntot = 0;
     const char     *title;
     bool            bRest;
     char            warn_buf[STRLEN];
 
-    title = gtypes[gtype];
+    title = shortName(gtype);
 
     snew(cbuf, natoms);
     /* Mark all id's as not set */
@@ -2733,16 +2730,13 @@ static bool do_numbering(int natoms, gmx_groups_t *groups,
     if (grps->nr == 1 && (ntot == 0 || ntot == natoms))
     {
         /* All atoms are part of one (or no) group, no index required */
-        groups->ngrpnr[gtype] = 0;
-        groups->grpnr[gtype]  = nullptr;
+        groups->groupNumbers[gtype].clear();
     }
     else
     {
-        groups->ngrpnr[gtype] = natoms;
-        snew(groups->grpnr[gtype], natoms);
-        for (j = 0; (j < natoms); j++)
+        for (int j = 0; (j < natoms); j++)
         {
-            groups->grpnr[gtype][j] = cbuf[j];
+            groups->groupNumbers[gtype].emplace_back(cbuf[j]);
         }
     }
 
@@ -2755,11 +2749,11 @@ static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames)
 {
     t_grpopts              *opts;
     pull_params_t          *pull;
-    int                     natoms, ai, aj, i, j, d, g, imin, jmin;
+    int                     natoms, imin, jmin;
     int                    *nrdf2, *na_vcm, na_tot;
     double                 *nrdf_tc, *nrdf_vcm, nrdf_uc, *nrdf_vcm_sub;
     ivec                   *dof_vcm;
-    int                     mol, ftype, as;
+    int                     as;
 
     /* Calculate nrdf.
      * First calc 3xnr-atoms for each group
@@ -2770,31 +2764,30 @@ static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames)
 
     opts = &ir->opts;
 
-    const gmx_groups_t &groups = mtop->groups;
+    const SimulationGroups &groups = mtop->groups;
     natoms = mtop->natoms;
 
     /* Allocate one more for a possible rest group */
     /* We need to sum degrees of freedom into doubles,
      * since floats give too low nrdf's above 3 million atoms.
      */
-    snew(nrdf_tc, groups.grps[egcTC].nr+1);
-    snew(nrdf_vcm, groups.grps[egcVCM].nr+1);
-    snew(dof_vcm, groups.grps[egcVCM].nr+1);
-    snew(na_vcm, groups.grps[egcVCM].nr+1);
-    snew(nrdf_vcm_sub, groups.grps[egcVCM].nr+1);
+    snew(nrdf_tc, groups.groups[SimulationAtomGroupType::TemperatureCoupling].nr+1);
+    snew(nrdf_vcm, groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval].nr+1);
+    snew(dof_vcm, groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval].nr+1);
+    snew(na_vcm, groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval].nr+1);
+    snew(nrdf_vcm_sub, groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval].nr+1);
 
-    for (i = 0; i < groups.grps[egcTC].nr; i++)
+    for (int i = 0; i < groups.groups[SimulationAtomGroupType::TemperatureCoupling].nr; i++)
     {
         nrdf_tc[i] = 0;
     }
-    for (i = 0; i < groups.grps[egcVCM].nr+1; i++)
+    for (int i = 0; i < groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval].nr+1; i++)
     {
         nrdf_vcm[i]     = 0;
         clear_ivec(dof_vcm[i]);
         na_vcm[i]       = 0;
         nrdf_vcm_sub[i] = 0;
     }
-
     snew(nrdf2, natoms);
     for (const AtomProxy atomP : AtomRange(*mtop))
     {
@@ -2803,7 +2796,7 @@ static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames)
         nrdf2[i] = 0;
         if (local.ptype == eptAtom || local.ptype == eptNucleus)
         {
-            g = getGroupType(groups, egcFREEZE, i);
+            int g = getGroupType(groups, SimulationAtomGroupType::Freeze, i);
             for (int d = 0; d < DIM; d++)
             {
                 if (opts->nFreeze[g][d] == 0)
@@ -2811,11 +2804,11 @@ static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames)
                     /* Add one DOF for particle i (counted as 2*1) */
                     nrdf2[i]                              += 2;
                     /* VCM group i has dim d as a DOF */
-                    dof_vcm[getGroupType(groups, egcVCM, i)][d]  = 1;
+                    dof_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, i)][d]  = 1;
                 }
             }
-            nrdf_tc [getGroupType(groups, egcTC, i)]  += 0.5*nrdf2[i];
-            nrdf_vcm[getGroupType(groups, egcVCM, i)] += 0.5*nrdf2[i];
+            nrdf_tc [getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, i)]       += 0.5*nrdf2[i];
+            nrdf_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, i)] += 0.5*nrdf2[i];
         }
     }
 
@@ -2824,12 +2817,12 @@ static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames)
     {
         const gmx_moltype_t &molt = mtop->moltype[molb.type];
         const t_atom        *atom = molt.atoms.atom;
-        for (mol = 0; mol < molb.nmol; mol++)
+        for (int mol = 0; mol < molb.nmol; mol++)
         {
-            for (ftype = F_CONSTR; ftype <= F_CONSTRNC; ftype++)
+            for (int ftype = F_CONSTR; ftype <= F_CONSTRNC; ftype++)
             {
                 gmx::ArrayRef<const int> ia = molt.ilist[ftype].iatoms;
-                for (i = 0; i < molt.ilist[ftype].size(); )
+                for (int i = 0; i < molt.ilist[ftype].size(); )
                 {
                     /* Subtract degrees of freedom for the constraints,
                      * if the particles still have degrees of freedom left.
@@ -2838,8 +2831,8 @@ static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames)
                      * contribute to the constraints the degrees of freedom do not
                      * change.
                      */
-                    ai = as + ia[i + 1];
-                    aj = as + ia[i + 2];
+                    int ai = as + ia[i + 1];
+                    int aj = as + ia[i + 2];
                     if (((atom[ia[i + 1]].ptype == eptNucleus) ||
                          (atom[ia[i + 1]].ptype == eptAtom)) &&
                         ((atom[ia[i + 2]].ptype == eptNucleus) ||
@@ -2865,25 +2858,25 @@ static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames)
                         jmin       = std::min(jmin, nrdf2[aj]);
                         nrdf2[ai] -= imin;
                         nrdf2[aj] -= jmin;
-                        nrdf_tc [getGroupType(groups, egcTC, ai)]  -= 0.5*imin;
-                        nrdf_tc [getGroupType(groups, egcTC, aj)]  -= 0.5*jmin;
-                        nrdf_vcm[getGroupType(groups, egcVCM, ai)] -= 0.5*imin;
-                        nrdf_vcm[getGroupType(groups, egcVCM, aj)] -= 0.5*jmin;
+                        nrdf_tc [getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, ai)]       -= 0.5*imin;
+                        nrdf_tc [getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, aj)]       -= 0.5*jmin;
+                        nrdf_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, ai)] -= 0.5*imin;
+                        nrdf_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, aj)] -= 0.5*jmin;
                     }
                     i  += interaction_function[ftype].nratoms+1;
                 }
             }
             gmx::ArrayRef<const int> ia = molt.ilist[F_SETTLE].iatoms;
-            for (i = 0; i < molt.ilist[F_SETTLE].size(); )
+            for (int i = 0; i < molt.ilist[F_SETTLE].size(); )
             {
                 /* Subtract 1 dof from every atom in the SETTLE */
-                for (j = 0; j < 3; j++)
+                for (int j = 0; j < 3; j++)
                 {
-                    ai         = as + ia[i + 1 + j];
+                    int ai         = as + ia[i + 1 + j];
                     imin       = std::min(2, nrdf2[ai]);
                     nrdf2[ai] -= imin;
-                    nrdf_tc [getGroupType(groups, egcTC, ai)]  -= 0.5*imin;
-                    nrdf_vcm[getGroupType(groups, egcVCM, ai)] -= 0.5*imin;
+                    nrdf_tc [getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, ai)]       -= 0.5*imin;
+                    nrdf_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, ai)] -= 0.5*imin;
                 }
                 i  += 4;
             }
@@ -2901,7 +2894,7 @@ static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames)
          */
         pull = ir->pull;
 
-        for (i = 0; i < pull->ncoord; i++)
+        for (int i = 0; i < pull->ncoord; i++)
         {
             if (pull->coord[i].eType != epullCONSTRAINT)
             {
@@ -2910,7 +2903,7 @@ static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames)
 
             imin = 1;
 
-            for (j = 0; j < 2; j++)
+            for (int j = 0; j < 2; j++)
             {
                 const t_pull_group *pgrp;
 
@@ -2919,12 +2912,12 @@ static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames)
                 if (pgrp->nat > 0)
                 {
                     /* Subtract 1/2 dof from each group */
-                    ai = pgrp->ind[0];
-                    nrdf_tc [getGroupType(groups, egcTC, ai)]  -= 0.5*imin;
-                    nrdf_vcm[getGroupType(groups, egcVCM, ai)] -= 0.5*imin;
-                    if (nrdf_tc[getGroupType(groups, egcTC, ai)] < 0)
+                    int ai = pgrp->ind[0];
+                    nrdf_tc [getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, ai)]       -= 0.5*imin;
+                    nrdf_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, ai)] -= 0.5*imin;
+                    if (nrdf_tc[getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, ai)] < 0)
                     {
-                        gmx_fatal(FARGS, "Center of mass pulling constraints caused the number of degrees of freedom for temperature coupling group %s to be negative", gnames[groups.grps[egcTC].nm_ind[getGroupType(groups, egcTC, ai)]]);
+                        gmx_fatal(FARGS, "Center of mass pulling constraints caused the number of degrees of freedom for temperature coupling group %s to be negative", gnames[groups.groups[SimulationAtomGroupType::TemperatureCoupling].nm_ind[getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, ai)]]);
                     }
                 }
                 else
@@ -2947,14 +2940,14 @@ static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames)
          * the number of degrees of freedom in each vcm group when COM
          * translation is removed and 6 when rotation is removed as well.
          */
-        for (j = 0; j < groups.grps[egcVCM].nr+1; j++)
+        for (int j = 0; j < groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval].nr+1; j++)
         {
             switch (ir->comm_mode)
             {
                 case ecmLINEAR:
                 case ecmLINEAR_ACCELERATION_CORRECTION:
                     nrdf_vcm_sub[j] = 0;
-                    for (d = 0; d < ndim_rm_vcm; d++)
+                    for (int d = 0; d < ndim_rm_vcm; d++)
                     {
                         if (dof_vcm[j][d])
                         {
@@ -2970,19 +2963,19 @@ static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames)
             }
         }
 
-        for (i = 0; i < groups.grps[egcTC].nr; i++)
+        for (int i = 0; i < groups.groups[SimulationAtomGroupType::TemperatureCoupling].nr; i++)
         {
             /* Count the number of atoms of TC group i for every VCM group */
-            for (j = 0; j < groups.grps[egcVCM].nr+1; j++)
+            for (int j = 0; j < groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval].nr+1; j++)
             {
                 na_vcm[j] = 0;
             }
             na_tot = 0;
-            for (ai = 0; ai < natoms; ai++)
+            for (int ai = 0; ai < natoms; ai++)
             {
-                if (getGroupType(groups, egcTC, ai) == i)
+                if (getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, ai) == i)
                 {
-                    na_vcm[getGroupType(groups, egcVCM, ai)]++;
+                    na_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, ai)]++;
                     na_tot++;
                 }
             }
@@ -2991,7 +2984,7 @@ static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames)
              */
             nrdf_uc    = nrdf_tc[i];
             nrdf_tc[i] = 0;
-            for (j = 0; j < groups.grps[egcVCM].nr+1; j++)
+            for (int j = 0; j < groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval].nr+1; j++)
             {
                 if (nrdf_vcm[j] > nrdf_vcm_sub[j])
                 {
@@ -3001,7 +2994,7 @@ static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames)
             }
         }
     }
-    for (i = 0; (i < groups.grps[egcTC].nr); i++)
+    for (int i = 0; (i < groups.groups[SimulationAtomGroupType::TemperatureCoupling].nr); i++)
     {
         opts->nrdf[i] = nrdf_tc[i];
         if (opts->nrdf[i] < 0)
@@ -3010,7 +3003,7 @@ static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames)
         }
         fprintf(stderr,
                 "Number of degrees of freedom in T-Coupling group %s is %.2f\n",
-                gnames[groups.grps[egcTC].nm_ind[i]], opts->nrdf[i]);
+                gnames[groups.groups[SimulationAtomGroupType::TemperatureCoupling].nm_ind[i]], opts->nrdf[i]);
     }
 
     sfree(nrdf2);
@@ -3021,7 +3014,7 @@ static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames)
     sfree(nrdf_vcm_sub);
 }
 
-static bool do_egp_flag(t_inputrec *ir, gmx_groups_t *groups,
+static bool do_egp_flag(t_inputrec *ir, SimulationGroups *groups,
                         const char *option, const char *val, int flag)
 {
     /* The maximum number of energy group pairs would be MAXPTR*(MAXPTR+1)/2.
@@ -3030,23 +3023,21 @@ static bool do_egp_flag(t_inputrec *ir, gmx_groups_t *groups,
      */
 #define EGP_MAX (STRLEN/2)
     int      j, k, nr;
-    char  ***gnames;
     bool     bSet;
 
-    gnames = groups->grpname;
-
-    auto names = gmx::splitString(val);
+    auto     names = gmx::splitString(val);
     if (names.size() % 2 != 0)
     {
         gmx_fatal(FARGS, "The number of groups for %s is odd", option);
     }
-    nr   = groups->grps[egcENER].nr;
+    nr   = groups->groups[SimulationAtomGroupType::EnergyOutput].nr;
     bSet = FALSE;
     for (size_t i = 0; i < names.size() / 2; i++)
     {
+        // TODO this needs to be replaced by a solution using std::find_if
         j = 0;
         while ((j < nr) &&
-               gmx_strcasecmp(names[2*i].c_str(), *(gnames[groups->grps[egcENER].nm_ind[j]])))
+               gmx_strcasecmp(names[2*i].c_str(), *(groups->groupNames[groups->groups[SimulationAtomGroupType::EnergyOutput].nm_ind[j]])))
         {
             j++;
         }
@@ -3057,7 +3048,7 @@ static bool do_egp_flag(t_inputrec *ir, gmx_groups_t *groups,
         }
         k = 0;
         while ((k < nr) &&
-               gmx_strcasecmp(names[2*i+1].c_str(), *(gnames[groups->grps[egcENER].nm_ind[k]])))
+               gmx_strcasecmp(names[2*i+1].c_str(), *(groups->groupNames[groups->groups[SimulationAtomGroupType::EnergyOutput].nm_ind[k]])))
         {
             k++;
         }
@@ -3145,18 +3136,17 @@ void do_index(const char* mdparin, const char *ndx,
               t_inputrec *ir,
               warninp_t wi)
 {
-    t_blocka     *grps;
-    gmx_groups_t *groups;
-    int           natoms;
-    t_symtab     *symtab;
-    t_atoms       atoms_all;
-    char          warnbuf[STRLEN], **gnames;
-    int           nr;
-    real          tau_min;
-    int           nstcmin;
-    int           i, j, k, restnm;
-    bool          bExcl, bTable, bAnneal, bRest;
-    char          warn_buf[STRLEN];
+    t_blocka *defaultIndexGroups;
+    int       natoms;
+    t_symtab *symtab;
+    t_atoms   atoms_all;
+    char      warnbuf[STRLEN], **gnames;
+    int       nr;
+    real      tau_min;
+    int       nstcmin;
+    int       i, j, k, restnm;
+    bool      bExcl, bTable, bAnneal, bRest;
+    char      warn_buf[STRLEN];
 
     if (bVerbose)
     {
@@ -3164,33 +3154,31 @@ void do_index(const char* mdparin, const char *ndx,
     }
     if (ndx == nullptr)
     {
-        snew(grps, 1);
-        snew(grps->index, 1);
+        snew(defaultIndexGroups, 1);
+        snew(defaultIndexGroups->index, 1);
         snew(gnames, 1);
         atoms_all = gmx_mtop_global_atoms(mtop);
-        analyse(&atoms_all, grps, &gnames, FALSE, TRUE);
+        analyse(&atoms_all, defaultIndexGroups, &gnames, FALSE, TRUE);
         done_atom(&atoms_all);
     }
     else
     {
-        grps = init_index(ndx, &gnames);
+        defaultIndexGroups = init_index(ndx, &gnames);
     }
 
-    groups = &mtop->groups;
+    SimulationGroups *groups = &mtop->groups;
     natoms = mtop->natoms;
     symtab = &mtop->symtab;
 
-    snew(groups->grpname, grps->nr+1);
-
-    for (i = 0; (i < grps->nr); i++)
+    for (int i = 0; (i < defaultIndexGroups->nr); i++)
     {
-        groups->grpname[i] = put_symtab(symtab, gnames[i]);
+        groups->groupNames.emplace_back(put_symtab(symtab, gnames[i]));
     }
-    groups->grpname[i] = put_symtab(symtab, "rest");
-    restnm             = i;
-    srenew(gnames, grps->nr+1);
-    gnames[restnm]   = *(groups->grpname[i]);
-    groups->ngrpname = grps->nr+1;
+    groups->groupNames.emplace_back(put_symtab(symtab, "rest"));
+    restnm             = groups->groupNames.size() - 1;
+    GMX_RELEASE_ASSERT(restnm == defaultIndexGroups->nr, "Size of allocations must match");
+    srenew(gnames, defaultIndexGroups->nr+1);
+    gnames[restnm]   = *(groups->groupNames.back());
 
     set_warning_line(wi, mdparin, -1);
 
@@ -3208,9 +3196,10 @@ void do_index(const char* mdparin, const char *ndx,
     }
 
     const bool useReferenceTemperature = integratorHasReferenceTemperature(ir);
-    do_numbering(natoms, groups, temperatureCouplingGroupNames, grps, gnames, egcTC,
+    do_numbering(natoms, groups, temperatureCouplingGroupNames, defaultIndexGroups, gnames,
+                 SimulationAtomGroupType::TemperatureCoupling,
                  restnm, useReferenceTemperature ? egrptpALL : egrptpALL_GENREST, bVerbose, wi);
-    nr            = groups->grps[egcTC].nr;
+    nr            = groups->groups[SimulationAtomGroupType::TemperatureCoupling].nr;
     ir->opts.ngtc = nr;
     snew(ir->opts.nrdf, nr);
     snew(ir->opts.tau_t, nr);
@@ -3436,9 +3425,9 @@ void do_index(const char* mdparin, const char *ndx,
                 {
                     if (ir->opts.annealing[i] != eannNO)
                     {
-                        j = groups->grps[egcTC].nm_ind[i];
+                        j = groups->groups[SimulationAtomGroupType::TemperatureCoupling].nm_ind[i];
                         fprintf(stderr, "Simulated annealing for group %s: %s, %d timepoints\n",
-                                *(groups->grpname[j]), eann_names[ir->opts.annealing[i]],
+                                *(groups->groupNames[j]), eann_names[ir->opts.annealing[i]],
                                 ir->opts.anneal_npoints[i]);
                         fprintf(stderr, "Time (ps)   Temperature (K)\n");
                         /* All terms except the last one */
@@ -3469,25 +3458,25 @@ void do_index(const char* mdparin, const char *ndx,
 
     if (ir->bPull)
     {
-        make_pull_groups(ir->pull, is->pull_grp, grps, gnames);
+        make_pull_groups(ir->pull, is->pull_grp, defaultIndexGroups, gnames);
 
         make_pull_coords(ir->pull);
     }
 
     if (ir->bRot)
     {
-        make_rotation_groups(ir->rot, is->rot_grp, grps, gnames);
+        make_rotation_groups(ir->rot, is->rot_grp, defaultIndexGroups, gnames);
     }
 
     if (ir->eSwapCoords != eswapNO)
     {
-        make_swap_groups(ir->swap, grps, gnames);
+        make_swap_groups(ir->swap, defaultIndexGroups, gnames);
     }
 
     /* Make indices for IMD session */
     if (ir->bIMD)
     {
-        make_IMD_group(ir->imd, is->imd_grp, grps, gnames);
+        make_IMD_group(ir->imd, is->imd_grp, defaultIndexGroups, gnames);
     }
 
     auto accelerations          = gmx::splitString(is->acc);
@@ -3497,9 +3486,10 @@ void do_index(const char* mdparin, const char *ndx,
         gmx_fatal(FARGS, "Invalid Acceleration input: %zu groups and %zu acc. values",
                   accelerationGroupNames.size(), accelerations.size());
     }
-    do_numbering(natoms, groups, accelerationGroupNames, grps, gnames, egcACC,
+    do_numbering(natoms, groups, accelerationGroupNames, defaultIndexGroups, gnames,
+                 SimulationAtomGroupType::Acceleration,
                  restnm, egrptpALL_GENREST, bVerbose, wi);
-    nr = groups->grps[egcACC].nr;
+    nr = groups->groups[SimulationAtomGroupType::Acceleration].nr;
     snew(ir->opts.acc, nr);
     ir->opts.ngacc = nr;
 
@@ -3512,9 +3502,10 @@ void do_index(const char* mdparin, const char *ndx,
         gmx_fatal(FARGS, "Invalid Freezing input: %zu groups and %zu freeze values",
                   freezeGroupNames.size(), freezeDims.size());
     }
-    do_numbering(natoms, groups, freezeGroupNames, grps, gnames, egcFREEZE,
+    do_numbering(natoms, groups, freezeGroupNames, defaultIndexGroups, gnames,
+                 SimulationAtomGroupType::Freeze,
                  restnm, egrptpALL_GENREST, bVerbose, wi);
-    nr             = groups->grps[egcFREEZE].nr;
+    nr             = groups->groups[SimulationAtomGroupType::Freeze].nr;
     ir->opts.ngfrz = nr;
     snew(ir->opts.nFreeze, nr);
     for (i = k = 0; (size_t(i) < freezeGroupNames.size()); i++)
@@ -3542,13 +3533,15 @@ void do_index(const char* mdparin, const char *ndx,
     }
 
     auto energyGroupNames = gmx::splitString(is->energy);
-    do_numbering(natoms, groups, energyGroupNames, grps, gnames, egcENER,
+    do_numbering(natoms, groups, energyGroupNames, defaultIndexGroups, gnames,
+                 SimulationAtomGroupType::EnergyOutput,
                  restnm, egrptpALL_GENREST, bVerbose, wi);
     add_wall_energrps(groups, ir->nwall, symtab);
-    ir->opts.ngener = groups->grps[egcENER].nr;
+    ir->opts.ngener = groups->groups[SimulationAtomGroupType::EnergyOutput].nr;
     auto vcmGroupNames = gmx::splitString(is->vcm);
     bRest           =
-        do_numbering(natoms, groups, vcmGroupNames, grps, gnames, egcVCM,
+        do_numbering(natoms, groups, vcmGroupNames, defaultIndexGroups, gnames,
+                     SimulationAtomGroupType::MassCenterVelocityRemoval,
                      restnm, vcmGroupNames.empty() ? egrptpALL_GENREST : egrptpPART, bVerbose, wi);
     if (bRest)
     {
@@ -3561,16 +3554,20 @@ void do_index(const char* mdparin, const char *ndx,
     calc_nrdf(mtop, ir, gnames);
 
     auto user1GroupNames = gmx::splitString(is->user1);
-    do_numbering(natoms, groups, user1GroupNames, grps, gnames, egcUser1,
+    do_numbering(natoms, groups, user1GroupNames, defaultIndexGroups, gnames,
+                 SimulationAtomGroupType::User1,
                  restnm, egrptpALL_GENREST, bVerbose, wi);
     auto user2GroupNames = gmx::splitString(is->user2);
-    do_numbering(natoms, groups, user2GroupNames, grps, gnames, egcUser2,
+    do_numbering(natoms, groups, user2GroupNames, defaultIndexGroups, gnames,
+                 SimulationAtomGroupType::User2,
                  restnm, egrptpALL_GENREST, bVerbose, wi);
     auto compressedXGroupNames = gmx::splitString(is->x_compressed_groups);
-    do_numbering(natoms, groups, compressedXGroupNames, grps, gnames, egcCompressedX,
+    do_numbering(natoms, groups, compressedXGroupNames, defaultIndexGroups, gnames,
+                 SimulationAtomGroupType::CompressedPositionOutput,
                  restnm, egrptpONE, bVerbose, wi);
     auto orirefFitGroupNames = gmx::splitString(is->orirefitgrp);
-    do_numbering(natoms, groups, orirefFitGroupNames, grps, gnames, egcORFIT,
+    do_numbering(natoms, groups, orirefFitGroupNames, defaultIndexGroups, gnames,
+                 SimulationAtomGroupType::OrientationRestraintsFit,
                  restnm, egrptpALL_GENREST, bVerbose, wi);
 
     /* QMMM input processing */
@@ -3587,7 +3584,8 @@ void do_index(const char* mdparin, const char *ndx,
                       qmBasisSets.size(), qmMethods.size());
         }
         /* group rest, if any, is always MM! */
-        do_numbering(natoms, groups, qmGroupNames, grps, gnames, egcQMMM,
+        do_numbering(natoms, groups, qmGroupNames, defaultIndexGroups, gnames,
+                     SimulationAtomGroupType::QuantumMechanics,
                      restnm, egrptpALL_GENREST, bVerbose, wi);
         nr            = qmGroupNames.size(); /*atoms->grps[egcQMMM].nr;*/
         ir->opts.ngQM = qmGroupNames.size();
@@ -3641,7 +3639,8 @@ void do_index(const char* mdparin, const char *ndx,
             gmx_fatal(FARGS, "Currently, having more than one QM group in MiMiC is not supported");
         }
         /* group rest, if any, is always MM! */
-        do_numbering(natoms, groups, qmGroupNames, grps, gnames, egcQMMM,
+        do_numbering(natoms, groups, qmGroupNames, defaultIndexGroups, gnames,
+                     SimulationAtomGroupType::QuantumMechanics,
                      restnm, egrptpALL_GENREST, bVerbose, wi);
 
         ir->opts.ngQM = qmGroupNames.size();
@@ -3651,18 +3650,18 @@ void do_index(const char* mdparin, const char *ndx,
 
     if (bVerbose)
     {
-        for (i = 0; (i < egcNR); i++)
+        for (auto group : gmx::keysOf(groups->groups))
         {
-            fprintf(stderr, "%-16s has %d element(s):", gtypes[i], groups->grps[i].nr);
-            for (j = 0; (j < groups->grps[i].nr); j++)
+            fprintf(stderr, "%-16s has %d element(s):", shortName(group), groups->groups[group].nr);
+            for (int j = 0; (j < groups->groups[group].nr); j++)
             {
-                fprintf(stderr, " %s", *(groups->grpname[groups->grps[i].nm_ind[j]]));
+                fprintf(stderr, " %s", *(groups->groupNames[groups->groups[group].nm_ind[j]]));
             }
             fprintf(stderr, "\n");
         }
     }
 
-    nr = groups->grps[egcENER].nr;
+    nr = groups->groups[SimulationAtomGroupType::EnergyOutput].nr;
     snew(ir->opts.egp_flags, nr*nr);
 
     bExcl = do_egp_flag(ir, groups, "energygrp-excl", is->egpexcl, EGP_EXCL);
@@ -3694,13 +3693,13 @@ void do_index(const char* mdparin, const char *ndx,
                                       "by default, but it is recommended to set it to an explicit value!",
                                       ir->expandedvals->nstexpanded));
     }
-    for (i = 0; (i < grps->nr); i++)
+    for (i = 0; (i < defaultIndexGroups->nr); i++)
     {
         sfree(gnames[i]);
     }
     sfree(gnames);
-    done_blocka(grps);
-    sfree(grps);
+    done_blocka(defaultIndexGroups);
+    sfree(defaultIndexGroups);
 
 }
 
@@ -4137,7 +4136,7 @@ void triple_check(const char *mdparin, t_inputrec *ir, gmx_mtop_t *sys,
     }
 
     bAcc = FALSE;
-    for (i = 0; (i < sys->groups.grps[egcACC].nr); i++)
+    for (int i = 0; (i < sys->groups.groups[SimulationAtomGroupType::Acceleration].nr); i++)
     {
         for (m = 0; (m < DIM); m++)
         {
@@ -4150,15 +4149,15 @@ void triple_check(const char *mdparin, t_inputrec *ir, gmx_mtop_t *sys,
     if (bAcc)
     {
         clear_rvec(acc);
-        snew(mgrp, sys->groups.grps[egcACC].nr);
+        snew(mgrp, sys->groups.groups[SimulationAtomGroupType::Acceleration].nr);
         for (const AtomProxy atomP : AtomRange(*sys))
         {
             const t_atom &local = atomP.atom();
             int           i     = atomP.globalAtomNumber();
-            mgrp[getGroupType(sys->groups, egcACC, i)] += local.m;
+            mgrp[getGroupType(sys->groups, SimulationAtomGroupType::Acceleration, i)] += local.m;
         }
         mt = 0.0;
-        for (i = 0; (i < sys->groups.grps[egcACC].nr); i++)
+        for (i = 0; (i < sys->groups.groups[SimulationAtomGroupType::Acceleration].nr); i++)
         {
             for (m = 0; (m < DIM); m++)
             {
@@ -4177,7 +4176,7 @@ void triple_check(const char *mdparin, t_inputrec *ir, gmx_mtop_t *sys,
                 if (ir->nstcomm != 0 && m < ndof_com(ir))
                 {
                     acc[m] /= mt;
-                    for (i = 0; (i < sys->groups.grps[egcACC].nr); i++)
+                    for (i = 0; (i < sys->groups.groups[SimulationAtomGroupType::Acceleration].nr); i++)
                     {
                         ir->opts.acc[i][m] -= acc[m];
                     }
index e5508a3996fe65e6c391de7ca863cac1b55d9b7c..3c2a08577800ac7b7787565fdd18c97c6e875762 100644 (file)
@@ -47,7 +47,6 @@ namespace gmx
 class MDModules;
 }
 
-struct gmx_groups_t;
 struct gmx_mtop_t;
 struct gmx_output_env_t;
 struct pull_params_t;
index ca630939fff2dff1a009d7f29e5b743f6749ef88..05178c595660f67d064a7b78ce0ad0aafe11d588 100644 (file)
@@ -1313,7 +1313,7 @@ void generate_qmexcl(gmx_mtop_t *sys, t_inputrec *ir, warninp *wi, GmxQmmmMode q
     int              index_offset = 0;
     int              qm_nr        = 0;
 
-    grpnr = sys->groups.grpnr[egcQMMM];
+    grpnr = sys->groups.groupNumbers[SimulationAtomGroupType::QuantumMechanics].data();
 
     for (size_t mb = 0; mb < sys->molblock.size(); mb++)
     {
index 65fb5989db5755f8730fa25b25e1fad448d0d42b..e86c01d1f65ade156f4cee74485b2fa211a3e46a 100644 (file)
@@ -202,7 +202,7 @@ void init_orires(FILE                 *fplog,
     od->nref = 0;
     for (int i = 0; i < mtop->natoms; i++)
     {
-        if (getGroupType(mtop->groups, egcORFIT, i) == 0)
+        if (getGroupType(mtop->groups, SimulationAtomGroupType::OrientationRestraintsFit, i) == 0)
         {
             od->nref++;
         }
@@ -225,8 +225,8 @@ void init_orires(FILE                 *fplog,
     {
         const t_atom &local = atomP.atom();
         int           i     = atomP.globalAtomNumber();
-        if (mtop->groups.grpnr[egcORFIT] == nullptr ||
-            mtop->groups.grpnr[egcORFIT][i] == 0)
+        if (mtop->groups.groupNumbers[SimulationAtomGroupType::OrientationRestraintsFit].empty() ||
+            mtop->groups.groupNumbers[SimulationAtomGroupType::OrientationRestraintsFit][i] == 0)
         {
             /* Not correct for free-energy with changing masses */
             od->mref[j] = local.m;
index 4feac1f229c9578e9f92e89ad6ca98e165cbc1f5..ef7dd2ee503fd67da3614e00d2dfdf0bf47964db 100644 (file)
@@ -127,6 +127,32 @@ static void bc_strings(const t_commrec *cr, t_symtab *symtab, int nr, char ****n
     sfree(handle);
 }
 
+static void bc_strings_container(const t_commrec      *cr,
+                                 t_symtab             *symtab,
+                                 int                   nr,
+                                 std::vector<char **> *nm)
+{
+    std::vector<int> handle;
+    if (MASTER(cr))
+    {
+        for (int i = 0; (i < nr); i++)
+        {
+            handle.emplace_back(lookup_symtab(symtab, (*nm)[i]));
+        }
+    }
+    block_bc(cr, nr);
+    nblock_abc(cr, nr, &handle);
+
+    if (!MASTER(cr))
+    {
+        nm->resize(nr);
+        for (int i = 0; (i < nr); i++)
+        {
+            (*nm)[i] = get_symtab_handle(symtab, handle[i]);
+        }
+    }
+}
+
 static void bc_strings_resinfo(const t_commrec *cr, t_symtab *symtab,
                                int nr, t_resinfo *resinfo)
 {
@@ -196,15 +222,13 @@ static void bc_blocka(const t_commrec *cr, t_blocka *block)
     }
 }
 
-static void bc_grps(const t_commrec *cr, t_grps grps[])
+static void bc_grps(const t_commrec *cr, gmx::ArrayRef<t_grps> grps)
 {
-    int i;
-
-    for (i = 0; (i < egcNR); i++)
+    for (auto &group : grps)
     {
-        block_bc(cr, grps[i].nr);
-        snew_bc(cr, grps[i].nm_ind, grps[i].nr);
-        nblock_bc(cr, grps[i].nr, grps[i].nm_ind);
+        block_bc(cr, group.nr);
+        snew_bc(cr, group.nm_ind, group.nr);
+        nblock_bc(cr, group.nr, group.nm_ind);
     }
 }
 
@@ -224,18 +248,17 @@ static void bc_atoms(const t_commrec *cr, t_symtab *symtab, t_atoms *atoms)
 }
 
 static void bc_groups(const t_commrec *cr, t_symtab *symtab,
-                      int natoms, gmx_groups_t *groups)
+                      int natoms, SimulationGroups *groups)
 {
-    int g, n;
+    int n;
 
-    bc_grps(cr, groups->grps);
-    block_bc(cr, groups->ngrpname);
-    bc_strings(cr, symtab, groups->ngrpname, &groups->grpname);
-    for (g = 0; g < egcNR; g++)
+    bc_grps(cr, groups->groups);
+    bc_strings_container(cr, symtab, groups->groupNames.size(), &groups->groupNames);
+    for (auto group : gmx::keysOf(groups->groups))
     {
         if (MASTER(cr))
         {
-            if (groups->grpnr[g])
+            if (!groups->groupNumbers[group].empty())
             {
                 n = natoms;
             }
@@ -245,14 +268,9 @@ static void bc_groups(const t_commrec *cr, t_symtab *symtab,
             }
         }
         block_bc(cr, n);
-        if (n == 0)
-        {
-            groups->grpnr[g] = nullptr;
-        }
-        else
+        if (n != 0)
         {
-            snew_bc(cr, groups->grpnr[g], n);
-            nblock_bc(cr, n, groups->grpnr[g]);
+            nblock_abc(cr, n, &groups->groupNumbers[group]);
         }
     }
     if (debug)
index 4849bcfe288dcbc685ee379198f2d7d72cc73576..33607bc1af97ca03f4e23220893eb4fc47681432 100644 (file)
@@ -58,7 +58,7 @@ static int div_nsteps(int nsteps, int nst)
     }
 }
 
-double compute_io(const t_inputrec *ir, int natoms, const gmx_groups_t *groups,
+double compute_io(const t_inputrec *ir, int natoms, const SimulationGroups &groups,
                   int nrener, int nrepl)
 {
 
@@ -73,9 +73,10 @@ double compute_io(const t_inputrec *ir, int natoms, const gmx_groups_t *groups,
     nstxtc = div_nsteps(nsteps, ir->nstxout_compressed);
     if (ir->nstxout_compressed > 0)
     {
-        for (i = 0; i < natoms; i++)
+        for (int i = 0; i < natoms; i++)
         {
-            if (groups->grpnr[egcCompressedX] == nullptr || groups->grpnr[egcCompressedX][i] == 0)
+            if (groups.groupNumbers[SimulationAtomGroupType::CompressedPositionOutput].empty() ||
+                groups.groupNumbers[SimulationAtomGroupType::CompressedPositionOutput][i] == 0)
             {
                 nxtcatoms++;
             }
index 95f5ba8bda47c422025b90249909ecfcd5959eed..dbe6159c67e261d5d099ce72ac57bb269b1e43f8 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2011,2014,2015,2018, by the GROMACS development team, led by
+ * Copyright (c) 2011,2014,2015,2018,2019, 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.
 #ifndef GMX_MDLIB_COMPUTE_IO_H
 #define GMX_MDLIB_COMPUTE_IO_H
 
-struct gmx_groups_t;
+struct SimulationGroups;
 struct t_inputrec;
 
-double compute_io(const t_inputrec *ir, int natoms, const gmx_groups_t *groups,
+double compute_io(const t_inputrec *ir, int natoms, const SimulationGroups &groups,
                   int nrener, int nrepl);
 /* Return total output to be written from this simulation. */
 
index f90aabe1630fa82f45f46e729ae8187605d39da2..bee8e0cfba5511c67d7f6b770ac9bfb196f645ad 100644 (file)
@@ -164,50 +164,50 @@ t_mdebin *init_mdebin(ener_file_t       fp_ene,
                       FILE             *fp_dhdl,
                       bool              isRerun)
 {
-    const char         *ener_nm[F_NRE];
-    static const char  *vir_nm[] = {
+    const char                *ener_nm[F_NRE];
+    static const char         *vir_nm[] = {
         "Vir-XX", "Vir-XY", "Vir-XZ",
         "Vir-YX", "Vir-YY", "Vir-YZ",
         "Vir-ZX", "Vir-ZY", "Vir-ZZ"
     };
-    static const char  *sv_nm[] = {
+    static const char         *sv_nm[] = {
         "ShakeVir-XX", "ShakeVir-XY", "ShakeVir-XZ",
         "ShakeVir-YX", "ShakeVir-YY", "ShakeVir-YZ",
         "ShakeVir-ZX", "ShakeVir-ZY", "ShakeVir-ZZ"
     };
-    static const char  *fv_nm[] = {
+    static const char         *fv_nm[] = {
         "ForceVir-XX", "ForceVir-XY", "ForceVir-XZ",
         "ForceVir-YX", "ForceVir-YY", "ForceVir-YZ",
         "ForceVir-ZX", "ForceVir-ZY", "ForceVir-ZZ"
     };
-    static const char  *pres_nm[] = {
+    static const char         *pres_nm[] = {
         "Pres-XX", "Pres-XY", "Pres-XZ",
         "Pres-YX", "Pres-YY", "Pres-YZ",
         "Pres-ZX", "Pres-ZY", "Pres-ZZ"
     };
-    static const char  *surft_nm[] = {
+    static const char         *surft_nm[] = {
         "#Surf*SurfTen"
     };
-    static const char  *mu_nm[] = {
+    static const char         *mu_nm[] = {
         "Mu-X", "Mu-Y", "Mu-Z"
     };
-    static const char  *vcos_nm[] = {
+    static const char         *vcos_nm[] = {
         "2CosZ*Vel-X"
     };
-    static const char  *visc_nm[] = {
+    static const char         *visc_nm[] = {
         "1/Viscosity"
     };
-    static const char  *baro_nm[] = {
+    static const char         *baro_nm[] = {
         "Barostat"
     };
 
-    const gmx_groups_t *groups;
-    char              **gnm;
-    char                buf[256];
-    const char         *bufi;
-    t_mdebin           *md;
-    int                 i, j, ni, nj, n, k, kk, ncon, nset;
-    gmx_bool            bBHAM, b14;
+    const SimulationGroups    *groups;
+    char                     **gnm;
+    char                       buf[256];
+    const char                *bufi;
+    t_mdebin                  *md;
+    int                        i, j, ni, nj, n, k, kk, ncon, nset;
+    gmx_bool                   bBHAM, b14;
 
     snew(md, 1);
 
@@ -449,8 +449,7 @@ t_mdebin *init_mdebin(ener_file_t       fp_ene,
             md->nEc++;
         }
     }
-
-    n       = groups->grps[egcENER].nr;
+    n       = groups->groups[SimulationAtomGroupType::EnergyOutput].nr;
     md->nEg = n;
     md->nE  = (n*(n+1))/2;
 
@@ -463,18 +462,18 @@ t_mdebin *init_mdebin(ener_file_t       fp_ene,
         {
             snew(gnm[k], STRLEN);
         }
-        for (i = 0; (i < groups->grps[egcENER].nr); i++)
+        for (i = 0; (i < groups->groups[SimulationAtomGroupType::EnergyOutput].nr); i++)
         {
-            ni = groups->grps[egcENER].nm_ind[i];
-            for (j = i; (j < groups->grps[egcENER].nr); j++)
+            ni = groups->groups[SimulationAtomGroupType::EnergyOutput].nm_ind[i];
+            for (j = i; (j < groups->groups[SimulationAtomGroupType::EnergyOutput].nr); j++)
             {
-                nj = groups->grps[egcENER].nm_ind[j];
+                nj = groups->groups[SimulationAtomGroupType::EnergyOutput].nm_ind[j];
                 for (k = kk = 0; (k < egNR); k++)
                 {
                     if (md->bEInd[k])
                     {
                         sprintf(gnm[kk], "%s:%s-%s", egrp_nm[k],
-                                *(groups->grpname[ni]), *(groups->grpname[nj]));
+                                *(groups->groupNames[ni]), *(groups->groupNames[nj]));
                         kk++;
                     }
                 }
@@ -495,7 +494,7 @@ t_mdebin *init_mdebin(ener_file_t       fp_ene,
         }
     }
 
-    md->nTC  = isRerun ? 0 : groups->grps[egcTC].nr;
+    md->nTC  = isRerun ? 0 : groups->groups[SimulationAtomGroupType::TemperatureCoupling].nr;
     md->nNHC = ir->opts.nhchainlength; /* shorthand for number of NH chains */
     if (md->bMTTK)
     {
@@ -534,8 +533,8 @@ t_mdebin *init_mdebin(ener_file_t       fp_ene,
 
     for (i = 0; (i < md->nTC); i++)
     {
-        ni = groups->grps[egcTC].nm_ind[i];
-        sprintf(buf, "T-%s", *(groups->grpname[ni]));
+        ni = groups->groups[SimulationAtomGroupType::TemperatureCoupling].nm_ind[i];
+        sprintf(buf, "T-%s", *(groups->groupNames[ni]));
         grpnms[i] = gmx_strdup(buf);
     }
     md->itemp = get_ebin_space(md->ebin, md->nTC, grpnms,
@@ -549,8 +548,8 @@ t_mdebin *init_mdebin(ener_file_t       fp_ene,
             {
                 for (i = 0; (i < md->nTC); i++)
                 {
-                    ni   = groups->grps[egcTC].nm_ind[i];
-                    bufi = *(groups->grpname[ni]);
+                    ni   = groups->groups[SimulationAtomGroupType::TemperatureCoupling].nm_ind[i];
+                    bufi = *(groups->groupNames[ni]);
                     for (j = 0; (j < md->nNHC); j++)
                     {
                         sprintf(buf, "Xi-%d-%s", j, bufi);
@@ -582,8 +581,8 @@ t_mdebin *init_mdebin(ener_file_t       fp_ene,
             {
                 for (i = 0; (i < md->nTC); i++)
                 {
-                    ni   = groups->grps[egcTC].nm_ind[i];
-                    bufi = *(groups->grpname[ni]);
+                    ni   = groups->groups[SimulationAtomGroupType::TemperatureCoupling].nm_ind[i];
+                    bufi = *(groups->groupNames[ni]);
                     sprintf(buf, "Xi-%s", bufi);
                     grpnms[2*i] = gmx_strdup(buf);
                     sprintf(buf, "vXi-%s", bufi);
@@ -599,8 +598,8 @@ t_mdebin *init_mdebin(ener_file_t       fp_ene,
     {
         for (i = 0; (i < md->nTC); i++)
         {
-            ni = groups->grps[egcTC].nm_ind[i];
-            sprintf(buf, "Lamb-%s", *(groups->grpname[ni]));
+            ni = groups->groups[SimulationAtomGroupType::TemperatureCoupling].nm_ind[i];
+            sprintf(buf, "Lamb-%s", *(groups->groupNames[ni]));
             grpnms[i] = gmx_strdup(buf);
         }
         md->itc = get_ebin_space(md->ebin, md->mde_n, grpnms, "");
@@ -612,18 +611,18 @@ t_mdebin *init_mdebin(ener_file_t       fp_ene,
     }
     sfree(grpnms);
 
-    md->nU = groups->grps[egcACC].nr;
+    md->nU = groups->groups[SimulationAtomGroupType::Acceleration].nr;
     if (md->nU > 1)
     {
         snew(grpnms, 3*md->nU);
         for (i = 0; (i < md->nU); i++)
         {
-            ni = groups->grps[egcACC].nm_ind[i];
-            sprintf(buf, "Ux-%s", *(groups->grpname[ni]));
+            ni = groups->groups[SimulationAtomGroupType::Acceleration].nm_ind[i];
+            sprintf(buf, "Ux-%s", *(groups->groupNames[ni]));
             grpnms[3*i+XX] = gmx_strdup(buf);
-            sprintf(buf, "Uy-%s", *(groups->grpname[ni]));
+            sprintf(buf, "Uy-%s", *(groups->groupNames[ni]));
             grpnms[3*i+YY] = gmx_strdup(buf);
-            sprintf(buf, "Uz-%s", *(groups->grpname[ni]));
+            sprintf(buf, "Uz-%s", *(groups->groupNames[ni]));
             grpnms[3*i+ZZ] = gmx_strdup(buf);
         }
         md->iu = get_ebin_space(md->ebin, 3*md->nU, grpnms, unit_vel);
@@ -1319,7 +1318,7 @@ void print_ebin(ener_file_t fp_ene, gmx_bool bEne, gmx_bool bDR, gmx_bool bOR,
                 int64_t step, double time,
                 int mode,
                 t_mdebin *md, t_fcdata *fcd,
-                gmx_groups_t *groups, t_grpopts *opts,
+                SimulationGroups *groups, t_grpopts *opts,
                 gmx::Awh *awh)
 {
     /*static char **grpnms=NULL;*/
@@ -1482,7 +1481,7 @@ void print_ebin(ener_file_t fp_ene, gmx_bool bEne, gmx_bool bDR, gmx_bool bOR,
                 if (opts->annealing[i] != eannNO)
                 {
                     fprintf(log, "Current ref_t for group %s: %8.1f\n",
-                            *(groups->grpname[groups->grps[egcTC].nm_ind[i]]),
+                            *(groups->groupNames[groups->groups[SimulationAtomGroupType::TemperatureCoupling].nm_ind[i]]),
                             opts->ref_t[i]);
                 }
             }
@@ -1536,12 +1535,12 @@ void print_ebin(ener_file_t fp_ene, gmx_bool bEne, gmx_bool bDR, gmx_bool bOR,
                     n = 0;
                     for (i = 0; (i < md->nEg); i++)
                     {
-                        ni = groups->grps[egcENER].nm_ind[i];
+                        ni = groups->groups[SimulationAtomGroupType::EnergyOutput].nm_ind[i];
                         for (j = i; (j < md->nEg); j++)
                         {
-                            nj = groups->grps[egcENER].nm_ind[j];
-                            sprintf(buf, "%s-%s", *(groups->grpname[ni]),
-                                    *(groups->grpname[nj]));
+                            nj = groups->groups[SimulationAtomGroupType::EnergyOutput].nm_ind[j];
+                            sprintf(buf, "%s-%s", *(groups->groupNames[ni]),
+                                    *(groups->groupNames[nj]));
                             md->print_grpnms[n++] = gmx_strdup(buf);
                         }
                     }
@@ -1575,8 +1574,8 @@ void print_ebin(ener_file_t fp_ene, gmx_bool bEne, gmx_bool bDR, gmx_bool bOR,
                         "Group", "Ux", "Uy", "Uz");
                 for (i = 0; (i < md->nU); i++)
                 {
-                    ni = groups->grps[egcACC].nm_ind[i];
-                    fprintf(log, "%15s", *groups->grpname[ni]);
+                    ni = groups->groups[SimulationAtomGroupType::Acceleration].nm_ind[i];
+                    fprintf(log, "%15s", *groups->groupNames[ni]);
                     pr_ebin(log, md->ebin, md->iu+3*i, 3, 3, mode, FALSE);
                 }
                 fprintf(log, "\n");
@@ -1712,7 +1711,7 @@ void EnergyOutput::printStepToEnergyFile(ener_file *fp_ene, bool bEne, bool bDR,
                                          int64_t step, double time,
                                          int mode,
                                          t_fcdata *fcd,
-                                         gmx_groups_t *groups, t_grpopts *opts,
+                                         SimulationGroups *groups, t_grpopts *opts,
                                          gmx::Awh *awh)
 {
     print_ebin(fp_ene, bEne, bDR, bOR, log, step, time, mode,
index 7e705012217869522fa931058f4bc504d27e4b4c..98f743bedee84d3e76599100fddb9929b698a93b 100644 (file)
@@ -43,7 +43,7 @@ class energyhistory_t;
 struct ener_file;
 struct gmx_ekindata_t;
 struct gmx_enerdata_t;
-struct gmx_groups_t;
+struct SimulationGroups;
 struct gmx_mtop_t;
 struct gmx_output_env_t;
 struct t_ebin;
@@ -144,7 +144,7 @@ class EnergyOutput
                                    int64_t step, double time,
                                    int mode,
                                    t_fcdata *fcd,
-                                   gmx_groups_t *groups, t_grpopts *opts,
+                                   SimulationGroups *groups, t_grpopts *opts,
                                    gmx::Awh *awh);
         /*! \brief Get the number of energy terms recorded.
          *
index 13b2e8bcef9c29d987f92bbc75cc1377ba83abc6..fad43bb6041427e8d662eeefb5573f57e209a54c 100644 (file)
 #include "gromacs/utility/fatalerror.h"
 #include "gromacs/utility/smalloc.h"
 
-void ns(FILE               *fp,
-        t_forcerec         *fr,
-        matrix              box,
-        const gmx_groups_t *groups,
-        gmx_localtop_t     *top,
-        const t_mdatoms    *md,
-        const t_commrec    *cr,
-        t_nrnb             *nrnb,
-        gmx_bool            bFillGrid)
+void ns(FILE                      *fp,
+        t_forcerec                *fr,
+        matrix                     box,
+        const SimulationGroups    *groups,
+        gmx_localtop_t            *top,
+        const t_mdatoms           *md,
+        const t_commrec           *cr,
+        t_nrnb                    *nrnb,
+        gmx_bool                   bFillGrid)
 {
     int     nsearch;
 
index 580a0ce206919b7234b2df7a976e2fb89535e46c..47c947b14cc6c85af583f71e21cfa5f23b059a17 100644 (file)
@@ -45,7 +45,7 @@ class DDBalanceRegionHandler;
 struct gmx_edsam;
 struct gmx_enerdata_t;
 struct gmx_enfrot;
-struct gmx_groups_t;
+struct SimulationGroups;
 struct gmx_grppairener_t;
 struct gmx_localtop_t;
 struct gmx_multisim_t;
@@ -89,38 +89,38 @@ void sum_epot(gmx_grppairener_t *grpp, real *epot);
 void sum_dhdl(gmx_enerdata_t *enerd, gmx::ArrayRef<const real> lambda, t_lambda *fepvals);
 /* Sum the free energy contributions */
 
-void do_force(FILE                                     *log,
-              const t_commrec                          *cr,
-              const gmx_multisim_t                     *ms,
-              const t_inputrec                         *inputrec,
-              gmx::Awh                                 *awh,
-              gmx_enfrot                               *enforcedRotation,
-              int64_t                                   step,
-              t_nrnb                                   *nrnb,
-              gmx_wallcycle                            *wcycle,
+void do_force(FILE                                            *log,
+              const t_commrec                                 *cr,
+              const gmx_multisim_t                            *ms,
+              const t_inputrec                                *inputrec,
+              gmx::Awh                                        *awh,
+              gmx_enfrot                                      *enforcedRotation,
+              int64_t                                          step,
+              t_nrnb                                          *nrnb,
+              gmx_wallcycle                                   *wcycle,
               // TODO top can be const when the group scheme no longer
               // builds exclusions during neighbor searching within
               // do_force_cutsGROUP.
-              gmx_localtop_t                           *top,
-              const gmx_groups_t                       *groups,
-              matrix                                    box,
-              gmx::ArrayRefWithPadding<gmx::RVec>       coordinates,
-              history_t                                *hist,
-              gmx::ArrayRefWithPadding<gmx::RVec>       force,
-              tensor                                    vir_force,
-              const t_mdatoms                          *mdatoms,
-              gmx_enerdata_t                           *enerd,
-              t_fcdata                                 *fcd,
-              gmx::ArrayRef<real>                       lambda,
-              t_graph                                  *graph,
-              t_forcerec                               *fr,
-              gmx::PpForceWorkload                     *ppForceWorkload,
-              const gmx_vsite_t                        *vsite,
-              rvec                                      mu_tot,
-              double                                    t,
-              gmx_edsam                                *ed,
-              int                                       flags,
-              const DDBalanceRegionHandler             &ddBalanceRegionHandler);
+              gmx_localtop_t                                  *top,
+              const SimulationGroups                          *groups,
+              matrix                                           box,
+              gmx::ArrayRefWithPadding<gmx::RVec>              coordinates,
+              history_t                                       *hist,
+              gmx::ArrayRefWithPadding<gmx::RVec>              force,
+              tensor                                           vir_force,
+              const t_mdatoms                                 *mdatoms,
+              gmx_enerdata_t                                  *enerd,
+              t_fcdata                                        *fcd,
+              gmx::ArrayRef<real>                              lambda,
+              t_graph                                         *graph,
+              t_forcerec                                      *fr,
+              gmx::PpForceWorkload                            *ppForceWorkload,
+              const gmx_vsite_t                               *vsite,
+              rvec                                             mu_tot,
+              double                                           t,
+              gmx_edsam                                       *ed,
+              int                                              flags,
+              const DDBalanceRegionHandler                    &ddBalanceRegionHandler);
 
 /* Communicate coordinates (if parallel).
  * Do neighbor searching (if necessary).
@@ -131,15 +131,15 @@ void do_force(FILE                                     *log,
  * f is always required.
  */
 
-void ns(FILE               *fplog,
-        t_forcerec         *fr,
-        matrix              box,
-        const gmx_groups_t *groups,
-        gmx_localtop_t     *top,
-        const t_mdatoms    *md,
-        const t_commrec    *cr,
-        t_nrnb             *nrnb,
-        gmx_bool            bFillGrid);
+void ns(FILE                      *fplog,
+        t_forcerec                *fr,
+        matrix                     box,
+        const SimulationGroups    *groups,
+        gmx_localtop_t            *top,
+        const t_mdatoms           *md,
+        const t_commrec           *cr,
+        t_nrnb                    *nrnb,
+        gmx_bool                   bFillGrid);
 /* Call the neighborsearcher */
 
 void do_force_lowlevel(t_forcerec   *fr,
index 1d42ce69b2296f31094af903df90cb51e50e5d8b..56c5707d9273454f6b2217e37191b78d63da73d4 100644 (file)
@@ -489,9 +489,9 @@ check_solvent(FILE  *                fp,
             for (cg_mol = 0; cg_mol < cgs->nr; cg_mol++)
             {
                 check_solvent_cg(molt, cg_mol, nmol,
-                                 mtop->groups.grpnr[egcQMMM] ?
-                                 mtop->groups.grpnr[egcQMMM]+at_offset+am : nullptr,
-                                 &mtop->groups.grps[egcQMMM],
+                                 mtop->groups.groupNumbers[SimulationAtomGroupType::QuantumMechanics].empty() ?
+                                 nullptr : mtop->groups.groupNumbers[SimulationAtomGroupType::QuantumMechanics].data()+at_offset+am,
+                                 &mtop->groups.groups[SimulationAtomGroupType::QuantumMechanics],
                                  fr,
                                  &n_solvent_parameters, &solvent_parameters,
                                  cginfo_mb[mb].cginfo[cgm+cg_mol],
@@ -621,17 +621,17 @@ static cginfo_mb_t *init_cginfo_mb(FILE *fplog, const gmx_mtop_t *mtop,
             {
                 a0 = cgs->index[cg];
                 a1 = cgs->index[cg+1];
-                if (getGroupType(mtop->groups, egcENER, a_offset+am+a0) !=
-                    getGroupType(mtop->groups, egcENER, a_offset   +a0))
+                if (getGroupType(mtop->groups, SimulationAtomGroupType::QuantumMechanics, a_offset+am+a0) !=
+                    getGroupType(mtop->groups, SimulationAtomGroupType::QuantumMechanics, a_offset   +a0))
                 {
                     bId = FALSE;
                 }
-                if (mtop->groups.grpnr[egcQMMM] != nullptr)
+                if (!mtop->groups.groupNumbers[SimulationAtomGroupType::QuantumMechanics].empty())
                 {
                     for (ai = a0; ai < a1; ai++)
                     {
-                        if (mtop->groups.grpnr[egcQMMM][a_offset+am+ai] !=
-                            mtop->groups.grpnr[egcQMMM][a_offset   +ai])
+                        if (mtop->groups.groupNumbers[SimulationAtomGroupType::QuantumMechanics][a_offset+am+ai] !=
+                            mtop->groups.groupNumbers[SimulationAtomGroupType::QuantumMechanics][a_offset   +ai])
                         {
                             bId = FALSE;
                         }
@@ -678,7 +678,7 @@ static cginfo_mb_t *init_cginfo_mb(FILE *fplog, const gmx_mtop_t *mtop,
                 a1 = cgs->index[cg+1];
 
                 /* Store the energy group in cginfo */
-                gid = getGroupType(mtop->groups, egcENER, a_offset+am+a0);
+                gid = getGroupType(mtop->groups, SimulationAtomGroupType::EnergyOutput, a_offset+am+a0);
                 SET_CGINFO_GID(cginfo[cgm+cg], gid);
 
                 /* Check the intra/inter charge group exclusions */
@@ -2203,7 +2203,7 @@ void init_forcerec(FILE                             *fp,
         if (negptable > 0)
         {
             /* Read the special tables for certain energy group pairs */
-            nm_ind = mtop->groups.grps[egcENER].nm_ind;
+            nm_ind = mtop->groups.groups[SimulationAtomGroupType::EnergyOutput].nm_ind;
             for (egi = 0; egi < negp_pp; egi++)
             {
                 for (egj = egi; egj < negp_pp; egj++)
@@ -2217,8 +2217,8 @@ void init_forcerec(FILE                             *fp,
                         }
                         /* Read the table file with the two energy groups names appended */
                         make_nbf_tables(fp, ic, rtab, tabfn,
-                                        *mtop->groups.grpname[nm_ind[egi]],
-                                        *mtop->groups.grpname[nm_ind[egj]],
+                                        *mtop->groups.groupNames[nm_ind[egi]],
+                                        *mtop->groups.groupNames[nm_ind[egj]],
                                         &fr->nblists[m]);
                         m++;
                     }
@@ -2336,7 +2336,7 @@ void init_forcerec(FILE                             *fp,
     init_ns(fp, cr, fr->ns, fr, mtop);
 
     /* Initialize the thread working data for bonded interactions */
-    init_bonded_threading(fp, mtop->groups.grps[egcENER].nr,
+    init_bonded_threading(fp, mtop->groups.groups[SimulationAtomGroupType::EnergyOutput].nr,
                           &fr->bondedThreading);
 
     fr->nthread_ewc = gmx_omp_nthreads_get(emntBonded);
index c86de049ec7ac5a8f14d6395291d356740dda274..84d73f4fd386c4afe3457cee02730aa0156b7953 100644 (file)
@@ -124,11 +124,11 @@ makeMDAtoms(FILE *fp, const gmx_mtop_t &mtop, const t_inputrec &ir,
     snew(md, 1);
     mdAtoms->mdatoms_.reset(md);
 
-    md->nenergrp = mtop.groups.grps[egcENER].nr;
+    md->nenergrp = mtop.groups.groups[SimulationAtomGroupType::EnergyOutput].nr;
     md->bVCMgrps = FALSE;
     for (int i = 0; i < mtop.natoms; i++)
     {
-        if (getGroupType(mtop.groups, egcVCM, i) > 0)
+        if (getGroupType(mtop.groups, SimulationAtomGroupType::MassCenterVelocityRemoval, i) > 0)
         {
             md->bVCMgrps = TRUE;
         }
@@ -212,9 +212,9 @@ void atoms2md(const gmx_mtop_t *mtop, const t_inputrec *ir,
 
     opts = &ir->opts;
 
-    const gmx_groups_t &groups = mtop->groups;
+    const SimulationGroups    &groups = mtop->groups;
 
-    auto                md = mdAtoms->mdatoms();
+    auto                       md = mdAtoms->mdatoms();
     /* nindex>=0 indicates DD where we use an index */
     if (nindex >= 0)
     {
@@ -300,11 +300,11 @@ void atoms2md(const gmx_mtop_t *mtop, const t_inputrec *ir,
          * Therefore, when adding code, the user should use something like:
          * gprnrU1 = (md->cU1==NULL ? 0 : md->cU1[localatindex])
          */
-        if (mtop->groups.grpnr[egcUser1] != nullptr)
+        if (!mtop->groups.groupNumbers[SimulationAtomGroupType::User1].empty())
         {
             srenew(md->cU1, md->nalloc);
         }
-        if (mtop->groups.grpnr[egcUser2] != nullptr)
+        if (!mtop->groups.groupNumbers[SimulationAtomGroupType::User2].empty())
         {
             srenew(md->cU2, md->nalloc);
         }
@@ -315,7 +315,7 @@ void atoms2md(const gmx_mtop_t *mtop, const t_inputrec *ir,
         }
     }
 
-    int molb = 0;
+    int molb          = 0;
 
     nthreads = gmx_omp_nthreads_get(emntDefault);
 #pragma omp parallel for num_threads(nthreads) schedule(static) firstprivate(molb)
@@ -339,7 +339,7 @@ void atoms2md(const gmx_mtop_t *mtop, const t_inputrec *ir,
 
             if (md->cFREEZE)
             {
-                md->cFREEZE[i] = getGroupType(groups, egcFREEZE, ag);
+                md->cFREEZE[i] = getGroupType(groups, SimulationAtomGroupType::Freeze, ag);
             }
             if (EI_ENERGY_MINIMIZATION(ir->eI))
             {
@@ -367,7 +367,8 @@ void atoms2md(const gmx_mtop_t *mtop, const t_inputrec *ir,
                 else
                 {
                     /* The friction coefficient is mass/tau_t */
-                    fac = ir->delta_t/opts->tau_t[md->cTC ? groups.grpnr[egcTC][ag] : 0];
+                    fac = ir->delta_t/opts->tau_t[md->cTC ?
+                                                  groups.groupNumbers[SimulationAtomGroupType::TemperatureCoupling][ag] : 0];
                     mA  = 0.5*atom.m*fac;
                     mB  = 0.5*atom.mB*fac;
                 }
@@ -464,35 +465,35 @@ void atoms2md(const gmx_mtop_t *mtop, const t_inputrec *ir,
             md->ptype[i]    = atom.ptype;
             if (md->cTC)
             {
-                md->cTC[i]    = groups.grpnr[egcTC][ag];
+                md->cTC[i]    = groups.groupNumbers[SimulationAtomGroupType::TemperatureCoupling][ag];
             }
-            md->cENER[i]    = getGroupType(groups, egcENER, ag);
+            md->cENER[i]    = getGroupType(groups, SimulationAtomGroupType::EnergyOutput, ag);
             if (md->cACC)
             {
-                md->cACC[i]   = groups.grpnr[egcACC][ag];
+                md->cACC[i]   = groups.groupNumbers[SimulationAtomGroupType::Acceleration][ag];
             }
             if (md->cVCM)
             {
-                md->cVCM[i]       = groups.grpnr[egcVCM][ag];
+                md->cVCM[i]       = groups.groupNumbers[SimulationAtomGroupType::MassCenterVelocityRemoval][ag];
             }
             if (md->cORF)
             {
-                md->cORF[i]       = getGroupType(groups, egcORFIT, ag);
+                md->cORF[i]       = getGroupType(groups, SimulationAtomGroupType::OrientationRestraintsFit, ag);
             }
 
             if (md->cU1)
             {
-                md->cU1[i]        = groups.grpnr[egcUser1][ag];
+                md->cU1[i]        = groups.groupNumbers[SimulationAtomGroupType::User1][ag];
             }
             if (md->cU2)
             {
-                md->cU2[i]        = groups.grpnr[egcUser2][ag];
+                md->cU2[i]        = groups.groupNumbers[SimulationAtomGroupType::User2][ag];
             }
 
             if (ir->bQMMM)
             {
-                if (groups.grpnr[egcQMMM] == nullptr ||
-                    groups.grpnr[egcQMMM][ag] < groups.grps[egcQMMM].nr-1)
+                if (groups.groupNumbers[SimulationAtomGroupType::QuantumMechanics].empty() ||
+                    groups.groupNumbers[SimulationAtomGroupType::QuantumMechanics][ag] < groups.groups[SimulationAtomGroupType::QuantumMechanics].nr-1)
                 {
                     md->bQM[i]      = TRUE;
                 }
index 93967223fae2d9557b411723811669af0ce9958d..bdce179ba9a64b283f7f1a6f4bbcf9c15f75525c 100644 (file)
 #include "gromacs/utility/smalloc.h"
 
 struct gmx_mdoutf {
-    t_fileio               *fp_trn;
-    t_fileio               *fp_xtc;
-    gmx_tng_trajectory_t    tng;
-    gmx_tng_trajectory_t    tng_low_prec;
-    int                     x_compression_precision; /* only used by XTC output */
-    ener_file_t             fp_ene;
-    const char             *fn_cpt;
-    gmx_bool                bKeepAndNumCPT;
-    int                     eIntegrator;
-    gmx_bool                bExpanded;
-    int                     elamstats;
-    int                     simulation_part;
-    FILE                   *fp_dhdl;
-    int                     natoms_global;
-    int                     natoms_x_compressed;
-    gmx_groups_t           *groups; /* for compressed position writing */
-    gmx_wallcycle_t         wcycle;
-    rvec                   *f_global;
-    gmx::IMDOutputProvider *outputProvider;
+    t_fileio                      *fp_trn;
+    t_fileio                      *fp_xtc;
+    gmx_tng_trajectory_t           tng;
+    gmx_tng_trajectory_t           tng_low_prec;
+    int                            x_compression_precision; /* only used by XTC output */
+    ener_file_t                    fp_ene;
+    const char                    *fn_cpt;
+    gmx_bool                       bKeepAndNumCPT;
+    int                            eIntegrator;
+    gmx_bool                       bExpanded;
+    int                            elamstats;
+    int                            simulation_part;
+    FILE                          *fp_dhdl;
+    int                            natoms_global;
+    int                            natoms_x_compressed;
+    SimulationGroups              *groups; /* for compressed position writing */
+    gmx_wallcycle_t                wcycle;
+    rvec                          *f_global;
+    gmx::IMDOutputProvider        *outputProvider;
 };
 
 
@@ -209,7 +209,7 @@ gmx_mdoutf_t init_mdoutf(FILE *fplog, int nfile, const t_filenm fnm[],
         of->natoms_x_compressed = 0;
         for (i = 0; (i < top_global->natoms); i++)
         {
-            if (getGroupType(*of->groups, egcCompressedX, i) == 0)
+            if (getGroupType(*of->groups, SimulationAtomGroupType::CompressedPositionOutput, i) == 0)
             {
                 of->natoms_x_compressed++;
             }
@@ -361,7 +361,7 @@ void mdoutf_write_to_trajectory_files(FILE *fplog, const t_commrec *cr,
                 auto x = makeArrayRef(state_global->x);
                 for (i = 0, j = 0; (i < of->natoms_global); i++)
                 {
-                    if (getGroupType(*of->groups, egcCompressedX, i) == 0)
+                    if (getGroupType(*of->groups, SimulationAtomGroupType::CompressedPositionOutput, i) == 0)
                     {
                         copy_rvec(x[i], xxtc[j++]);
                     }
index c5647569662da57914c28b51ca99521c33820c4d..b2999ca05f02799871241ed4590a96e13050cce0 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017,2018,2019, 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.
@@ -250,7 +250,7 @@ static void get_input(const char *membed_input, real *xy_fac, real *xy_max, real
 
 /* Obtain the maximum and minimum coordinates of the group to be embedded */
 static int init_ins_at(t_block *ins_at, t_block *rest_at, t_state *state, pos_ins_t *pos_ins,
-                       gmx_groups_t *groups, int ins_grp_id, real xy_max)
+                       SimulationGroups *groups, int ins_grp_id, real xy_max)
 {
     int        i, gid, c = 0;
     real       xmin, xmax, ymin, ymax, zmin, zmax;
@@ -266,8 +266,8 @@ static int init_ins_at(t_block *ins_at, t_block *rest_at, t_state *state, pos_in
 
     for (i = 0; i < state->natoms; i++)
     {
-        gid = groups->grpnr[egcFREEZE][i];
-        if (groups->grps[egcFREEZE].nm_ind[gid] == ins_grp_id)
+        gid = groups->groupNumbers[SimulationAtomGroupType::Freeze][i];
+        if (groups->groups[SimulationAtomGroupType::Freeze].nm_ind[gid] == ins_grp_id)
         {
             xmin = std::min(xmin, x[i][XX]);
             xmax = std::max(xmax, x[i][XX]);
@@ -671,13 +671,13 @@ static int gen_rm_list(rm_t *rm_p, t_block *ins_at, t_block *rest_at, t_pbc *pbc
 }
 
 /*remove all lipids and waters overlapping and update all important structures (e.g. state and mtop)*/
-static void rm_group(gmx_groups_t *groups, gmx_mtop_t *mtop, rm_t *rm_p, t_state *state,
+static void rm_group(SimulationGroups *groups, gmx_mtop_t *mtop, rm_t *rm_p, t_state *state,
                      t_block *ins_at, pos_ins_t *pos_ins)
 {
     int             j, k, n, rm, mol_id, at, block;
     rvec           *x_tmp, *v_tmp;
     int            *list;
-    unsigned char  *new_egrp[egcNR];
+    gmx::EnumerationArray < SimulationAtomGroupType, std::vector < unsigned char>> new_egrp;
     gmx_bool        bRM;
     int             RMmolblock;
 
@@ -704,12 +704,12 @@ static void rm_group(gmx_groups_t *groups, gmx_mtop_t *mtop, rm_t *rm_p, t_state
     snew(x_tmp, state->natoms);
     snew(v_tmp, state->natoms);
 
-    for (int i = 0; i < egcNR; i++)
+    for (auto group : keysOf(groups->groupNumbers))
     {
-        if (groups->grpnr[i] != nullptr)
+        if (!groups->groupNumbers[group].empty())
         {
-            groups->ngrpnr[i] = state->natoms;
-            snew(new_egrp[i], state->natoms);
+            groups->groupNumbers[group].resize(state->natoms);
+            new_egrp[group].resize(state->natoms);
         }
     }
 
@@ -730,11 +730,11 @@ static void rm_group(gmx_groups_t *groups, gmx_mtop_t *mtop, rm_t *rm_p, t_state
 
         if (!bRM)
         {
-            for (j = 0; j < egcNR; j++)
+            for (auto group : keysOf(groups->groupNumbers))
             {
-                if (groups->grpnr[j] != nullptr)
+                if (!groups->groupNumbers[group].empty())
                 {
-                    new_egrp[j][i-rm] = groups->grpnr[j][i];
+                    new_egrp[group][i-rm] = groups->groupNumbers[group][i];
                 }
             }
             copy_rvec(x[i], x_tmp[i-rm]);
@@ -770,12 +770,11 @@ static void rm_group(gmx_groups_t *groups, gmx_mtop_t *mtop, rm_t *rm_p, t_state
     }
     sfree(v_tmp);
 
-    for (int i = 0; i < egcNR; i++)
+    for (auto group : keysOf(groups->groupNumbers))
     {
-        if (groups->grpnr[i] != nullptr)
+        if (!groups->groupNumbers[group].empty())
         {
-            sfree(groups->grpnr[i]);
-            groups->grpnr[i] = new_egrp[i];
+            groups->groupNumbers[group] = new_egrp[group];
         }
     }
 
@@ -962,48 +961,24 @@ void rescale_membed(int step_rel, gmx_membed_t *membed, rvec *x)
     resize(membed->r_ins, x, membed->pos_ins, membed->fac);
 }
 
-/* We would like gn to be const as well, but C doesn't allow this */
-/* TODO this is utility functionality (search for the index of a
-   string in a collection), so should be refactored and located more
-   centrally. Also, it nearly duplicates the same string in readir.c */
-static int search_string(const char *s, int ng, char *gn[])
-{
-    int i;
-
-    for (i = 0; (i < ng); i++)
-    {
-        if (gmx_strcasecmp(s, gn[i]) == 0)
-        {
-            return i;
-        }
-    }
-
-    gmx_fatal(FARGS,
-              "Group %s selected for embedding was not found in the index file.\n"
-              "Group names must match either [moleculetype] names or custom index group\n"
-              "names, in which case you must supply an index file to the '-n' option\n"
-              "of grompp.",
-              s);
-}
-
 gmx_membed_t *init_membed(FILE *fplog, int nfile, const t_filenm fnm[], gmx_mtop_t *mtop,
                           t_inputrec *inputrec, t_state *state, t_commrec *cr, real *cpt)
 {
-    char                     *ins, **gnames;
-    int                       i, rm_bonded_at, fr_id, fr_i = 0, tmp_id, warn = 0;
-    int                       ng, j, max_lip_rm, ins_grp_id, ntype, lip_rm;
-    real                      prot_area;
-    rvec                     *r_ins = nullptr;
-    t_block                  *ins_at, *rest_at;
-    pos_ins_t                *pos_ins;
-    mem_t                    *mem_p;
-    rm_t                     *rm_p;
-    gmx_groups_t             *groups;
-    gmx_bool                  bExcl = FALSE;
-    t_atoms                   atoms;
-    t_pbc                    *pbc;
-    char                    **piecename = nullptr;
-    gmx_membed_t             *membed    = nullptr;
+    char                            *ins;
+    int                              i, rm_bonded_at, fr_id, fr_i = 0, tmp_id, warn = 0;
+    int                              ng, j, max_lip_rm, ins_grp_id, ntype, lip_rm;
+    real                             prot_area;
+    rvec                            *r_ins = nullptr;
+    t_block                         *ins_at, *rest_at;
+    pos_ins_t                       *pos_ins;
+    mem_t                           *mem_p;
+    rm_t                            *rm_p;
+    SimulationGroups                *groups;
+    gmx_bool                         bExcl = FALSE;
+    t_atoms                          atoms;
+    t_pbc                           *pbc;
+    char                           **piecename = nullptr;
+    gmx_membed_t                    *membed    = nullptr;
 
     /* input variables */
     real        xy_fac           = 0.5;
@@ -1060,17 +1035,33 @@ gmx_membed_t *init_membed(FILE *fplog, int nfile, const t_filenm fnm[], gmx_mtop
             *cpt = -1;
         }
         groups = &(mtop->groups);
-        snew(gnames, groups->ngrpname);
-        for (i = 0; i < groups->ngrpname; i++)
+        std::vector<std::string> gnames;
+        for (const auto &groupName : groups->groupNames)
         {
-            gnames[i] = *(groups->grpname[i]);
+            gnames.emplace_back(*groupName);
         }
 
         atoms = gmx_mtop_global_atoms(mtop);
         snew(mem_p, 1);
         fprintf(stderr, "\nSelect a group to embed in the membrane:\n");
         get_index(&atoms, opt2fn_null("-mn", nfile, fnm), 1, &(ins_at->nr), &(ins_at->index), &ins);
-        ins_grp_id = search_string(ins, groups->ngrpname, gnames);
+
+        auto found = std::find_if(gnames.begin(), gnames.end(),
+                                  [&ins](const auto &name)
+                                  { return gmx::equalCaseInsensitive(ins, name); });
+
+        if (found == gnames.end())
+        {
+            gmx_fatal(FARGS,
+                      "Group %s selected for embedding was not found in the index file.\n"
+                      "Group names must match either [moleculetype] names or custom index group\n"
+                      "names, in which case you must supply an index file to the '-n' option\n"
+                      "of grompp.", ins);
+        }
+        else
+        {
+            ins_grp_id = std::distance(gnames.begin(), found);
+        }
         fprintf(stderr, "\nSelect a group to embed %s into (e.g. the membrane):\n", ins);
         get_index(&atoms, opt2fn_null("-mn", nfile, fnm), 1, &(mem_p->mem_at.nr), &(mem_p->mem_at.index), &(mem_p->name));
 
@@ -1136,7 +1127,7 @@ gmx_membed_t *init_membed(FILE *fplog, int nfile, const t_filenm fnm[], gmx_mtop
 
         for (i = 0; i < inputrec->opts.ngfrz; i++)
         {
-            tmp_id = mtop->groups.grps[egcFREEZE].nm_ind[i];
+            tmp_id = mtop->groups.groups[SimulationAtomGroupType::Freeze].nm_ind[i];
             if (ins_grp_id == tmp_id)
             {
                 fr_id = tmp_id;
@@ -1157,7 +1148,7 @@ gmx_membed_t *init_membed(FILE *fplog, int nfile, const t_filenm fnm[], gmx_mtop
             }
         }
 
-        ng = groups->grps[egcENER].nr;
+        ng = groups->groups[SimulationAtomGroupType::EnergyOutput].nr;
         if (ng == 1)
         {
             gmx_input("No energy groups defined. This is necessary for energy exclusion in the freeze group");
@@ -1170,12 +1161,12 @@ gmx_membed_t *init_membed(FILE *fplog, int nfile, const t_filenm fnm[], gmx_mtop
                 if (inputrec->opts.egp_flags[ng*i+j] == EGP_EXCL)
                 {
                     bExcl = TRUE;
-                    if ( (groups->grps[egcENER].nm_ind[i] != ins_grp_id) ||
-                         (groups->grps[egcENER].nm_ind[j] != ins_grp_id) )
+                    if ( (groups->groups[SimulationAtomGroupType::EnergyOutput].nm_ind[i] != ins_grp_id) ||
+                         (groups->groups[SimulationAtomGroupType::EnergyOutput].nm_ind[j] != ins_grp_id) )
                     {
                         gmx_fatal(FARGS, "Energy exclusions \"%s\" and  \"%s\" do not match the group "
-                                  "to embed \"%s\"", *groups->grpname[groups->grps[egcENER].nm_ind[i]],
-                                  *groups->grpname[groups->grps[egcENER].nm_ind[j]], ins);
+                                  "to embed \"%s\"", *groups->groupNames[groups->groups[SimulationAtomGroupType::EnergyOutput].nm_ind[i]],
+                                  *groups->groupNames[groups->groups[SimulationAtomGroupType::EnergyOutput].nm_ind[j]], ins);
                     }
                 }
             }
index f29c6820df74d6a1bbc1f8a6ba7f2d614e1c4478..e57045fa96f4f6bc5d9aa4fa049437769d5b2940 100644 (file)
@@ -2104,7 +2104,7 @@ void init_ns(FILE *fplog, const t_commrec *cr,
                   nr_in_cg, maxcg);
     }
 
-    ngid = mtop->groups.grps[egcENER].nr;
+    ngid = mtop->groups.groups[SimulationAtomGroupType::EnergyOutput].nr;
     snew(ns->bExcludeAlleg, ngid);
     for (i = 0; i < ngid; i++)
     {
@@ -2221,15 +2221,15 @@ void done_ns(gmx_ns_t *ns, int numEnergyGroups)
     sfree(ns);
 }
 
-int search_neighbours(FILE               *log,
-                      t_forcerec         *fr,
-                      matrix              box,
-                      gmx_localtop_t     *top,
-                      const gmx_groups_t *groups,
-                      const t_commrec    *cr,
-                      t_nrnb             *nrnb,
-                      const t_mdatoms    *md,
-                      gmx_bool            bFillGrid)
+int search_neighbours(FILE                      *log,
+                      t_forcerec                *fr,
+                      matrix                     box,
+                      gmx_localtop_t            *top,
+                      const SimulationGroups    *groups,
+                      const t_commrec           *cr,
+                      t_nrnb                    *nrnb,
+                      const t_mdatoms           *md,
+                      gmx_bool                   bFillGrid)
 {
     const t_block      *cgs = &(top->cgs);
     rvec                box_size, grid_x0, grid_x1;
@@ -2247,7 +2247,7 @@ int search_neighbours(FILE               *log,
 
     /* Set some local variables */
     bGrid = fr->bGrid;
-    ngid  = groups->grps[egcENER].nr;
+    ngid  = groups->groups[SimulationAtomGroupType::EnergyOutput].nr;
 
     for (m = 0; (m < DIM); m++)
     {
index da55cfb783299b46369d6669c3df071f9137bd07..c913fc2b2993049db58b26f5302473d8606fd1b4 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2018, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2018,2019, 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.
@@ -42,7 +42,7 @@
 #include "gromacs/math/vectypes.h"
 #include "gromacs/utility/basedefinitions.h"
 
-struct gmx_groups_t;
+struct SimulationGroups;
 struct gmx_localtop_t;
 struct gmx_mtop_t;
 struct gmx_ns_t;
@@ -86,15 +86,15 @@ void init_ns(FILE *fplog, const t_commrec *cr,
 //! Destructor.
 void done_ns(gmx_ns_t *ns, int numEnergyGroups);
 
-int search_neighbours(FILE               *log,
-                      t_forcerec         *fr,
-                      matrix              box,
-                      gmx_localtop_t     *top,
-                      const gmx_groups_t *groups,
-                      const t_commrec    *cr,
-                      t_nrnb             *nrnb,
-                      const t_mdatoms    *md,
-                      gmx_bool            bFillGrid);
+int search_neighbours(FILE                      *log,
+                      t_forcerec                *fr,
+                      matrix                     box,
+                      gmx_localtop_t            *top,
+                      const SimulationGroups    *groups,
+                      const t_commrec           *cr,
+                      t_nrnb                    *nrnb,
+                      const t_mdatoms           *md,
+                      gmx_bool                   bFillGrid);
 
 
 /* Debugging routines from wnblist.c */
index 643d6465585177ed677b9855fb3a28ff037952f8..cd014b9fd0e3796da37bf3fc05e2d3d2fd989f9a 100644 (file)
@@ -353,15 +353,15 @@ t_QMMMrec *mk_QMMMrec()
 
 std::vector<int> qmmmAtomIndices(const t_inputrec &ir, const gmx_mtop_t &mtop)
 {
-    const int           numQmmmGroups = ir.opts.ngQM;
-    const gmx_groups_t &groups        = mtop.groups;
-    std::vector<int>    qmmmAtoms;
+    const int                  numQmmmGroups = ir.opts.ngQM;
+    const SimulationGroups    &groups        = mtop.groups;
+    std::vector<int>           qmmmAtoms;
     for (int i = 0; i < numQmmmGroups; i++)
     {
         for (const AtomProxy atomP : AtomRange(mtop))
         {
             int index = atomP.globalAtomNumber();
-            if (getGroupType(groups, egcQMMM, index) == i)
+            if (getGroupType(groups, SimulationAtomGroupType::QuantumMechanics, index) == i)
             {
                 qmmmAtoms.push_back(index);
             }
@@ -382,9 +382,9 @@ std::vector<int> qmmmAtomIndices(const t_inputrec &ir, const gmx_mtop_t &mtop)
                     const int vsite = atomOffset + ilist.iatoms[j  ]; /* the vsite         */
                     const int ai    = atomOffset + ilist.iatoms[j+1]; /* constructing atom */
                     const int aj    = atomOffset + ilist.iatoms[j+2]; /* constructing atom */
-                    if (getGroupType(groups, egcQMMM, vsite) == getGroupType(groups, egcQMMM, ai)
+                    if (getGroupType(groups, SimulationAtomGroupType::QuantumMechanics, vsite) == getGroupType(groups, SimulationAtomGroupType::QuantumMechanics, ai)
                         &&
-                        getGroupType(groups, egcQMMM, vsite) == getGroupType(groups, egcQMMM, aj))
+                        getGroupType(groups, SimulationAtomGroupType::QuantumMechanics, vsite) == getGroupType(groups, SimulationAtomGroupType::QuantumMechanics, aj))
                     {
                         /* this dummy link atom needs to be removed from qmmmAtoms
                          * before making the QMrec of this layer!
index 9fa062db9c6c269e0e286bc4f17d9b94b5d38ac1..1917fd76755fa15f6a2075f0dfba051398af7b44 100644 (file)
@@ -964,34 +964,34 @@ static void init_adir(gmx_shellfc_t            *shfc,
                   nullptr, nullptr, gmx::ConstraintVariable::Deriv_FlexCon);
 }
 
-void relax_shell_flexcon(FILE                                     *fplog,
-                         const t_commrec                          *cr,
-                         const gmx_multisim_t                     *ms,
-                         gmx_bool                                  bVerbose,
-                         gmx_enfrot                               *enforcedRotation,
-                         int64_t                                   mdstep,
-                         const t_inputrec                         *inputrec,
-                         gmx_bool                                  bDoNS,
-                         int                                       force_flags,
-                         gmx_localtop_t                           *top,
-                         gmx::Constraints                         *constr,
-                         gmx_enerdata_t                           *enerd,
-                         t_fcdata                                 *fcd,
-                         t_state                                  *state,
-                         gmx::ArrayRefWithPadding<gmx::RVec>       f,
-                         tensor                                    force_vir,
-                         const t_mdatoms                          *md,
-                         t_nrnb                                   *nrnb,
-                         gmx_wallcycle_t                           wcycle,
-                         t_graph                                  *graph,
-                         const gmx_groups_t                       *groups,
-                         gmx_shellfc_t                            *shfc,
-                         t_forcerec                               *fr,
-                         gmx::PpForceWorkload                     *ppForceWorkload,
-                         double                                    t,
-                         rvec                                      mu_tot,
-                         const gmx_vsite_t                        *vsite,
-                         const DDBalanceRegionHandler             &ddBalanceRegionHandler)
+void relax_shell_flexcon(FILE                                            *fplog,
+                         const t_commrec                                 *cr,
+                         const gmx_multisim_t                            *ms,
+                         gmx_bool                                         bVerbose,
+                         gmx_enfrot                                      *enforcedRotation,
+                         int64_t                                          mdstep,
+                         const t_inputrec                                *inputrec,
+                         gmx_bool                                         bDoNS,
+                         int                                              force_flags,
+                         gmx_localtop_t                                  *top,
+                         gmx::Constraints                                *constr,
+                         gmx_enerdata_t                                  *enerd,
+                         t_fcdata                                        *fcd,
+                         t_state                                         *state,
+                         gmx::ArrayRefWithPadding<gmx::RVec>              f,
+                         tensor                                           force_vir,
+                         const t_mdatoms                                 *md,
+                         t_nrnb                                          *nrnb,
+                         gmx_wallcycle_t                                  wcycle,
+                         t_graph                                         *graph,
+                         const SimulationGroups                          *groups,
+                         gmx_shellfc_t                                   *shfc,
+                         t_forcerec                                      *fr,
+                         gmx::PpForceWorkload                            *ppForceWorkload,
+                         double                                           t,
+                         rvec                                             mu_tot,
+                         const gmx_vsite_t                               *vsite,
+                         const DDBalanceRegionHandler                    &ddBalanceRegionHandler)
 {
     int           nshell;
     t_shell      *shell;
index 913ee5efa83b40c6cede9cd84547b65d59a465bb..d5e60041874feb7487d92807a4d2264414990fb3 100644 (file)
@@ -46,7 +46,7 @@
 class DDBalanceRegionHandler;
 struct gmx_enerdata_t;
 struct gmx_enfrot;
-struct gmx_groups_t;
+struct SimulationGroups;
 struct gmx_multisim_t;
 struct gmx_shellfc_t;
 struct gmx_mtop_t;
@@ -75,34 +75,34 @@ void make_local_shells(const t_commrec *cr,
                        gmx_shellfc_t   *shfc);
 
 /* Optimize shell positions */
-void relax_shell_flexcon(FILE                                     *log,
-                         const t_commrec                          *cr,
-                         const gmx_multisim_t                     *ms,
-                         gmx_bool                                  bVerbose,
-                         gmx_enfrot                               *enforcedRotation,
-                         int64_t                                   mdstep,
-                         const t_inputrec                         *inputrec,
-                         gmx_bool                                  bDoNS,
-                         int                                       force_flags,
-                         gmx_localtop_t                           *top,
-                         gmx::Constraints                         *constr,
-                         gmx_enerdata_t                           *enerd,
-                         t_fcdata                                 *fcd,
-                         t_state                                  *state,
-                         gmx::ArrayRefWithPadding<gmx::RVec>       f,
-                         tensor                                    force_vir,
-                         const t_mdatoms                          *md,
-                         t_nrnb                                   *nrnb,
-                         gmx_wallcycle_t                           wcycle,
-                         t_graph                                  *graph,
-                         const gmx_groups_t                       *groups,
-                         gmx_shellfc_t                            *shfc,
-                         t_forcerec                               *fr,
-                         gmx::PpForceWorkload                     *ppForceWorkload,
-                         double                                    t,
-                         rvec                                      mu_tot,
-                         const gmx_vsite_t                        *vsite,
-                         const DDBalanceRegionHandler             &ddBalanceRegionHandler);
+void relax_shell_flexcon(FILE                                            *log,
+                         const t_commrec                                 *cr,
+                         const gmx_multisim_t                            *ms,
+                         gmx_bool                                         bVerbose,
+                         gmx_enfrot                                      *enforcedRotation,
+                         int64_t                                          mdstep,
+                         const t_inputrec                                *inputrec,
+                         gmx_bool                                         bDoNS,
+                         int                                              force_flags,
+                         gmx_localtop_t                                  *top,
+                         gmx::Constraints                                *constr,
+                         gmx_enerdata_t                                  *enerd,
+                         t_fcdata                                        *fcd,
+                         t_state                                         *state,
+                         gmx::ArrayRefWithPadding<gmx::RVec>              f,
+                         tensor                                           force_vir,
+                         const t_mdatoms                                 *md,
+                         t_nrnb                                          *nrnb,
+                         gmx_wallcycle_t                                  wcycle,
+                         t_graph                                         *graph,
+                         const SimulationGroups                          *groups,
+                         gmx_shellfc_t                                   *shfc,
+                         t_forcerec                                      *fr,
+                         gmx::PpForceWorkload                            *ppForceWorkload,
+                         double                                           t,
+                         rvec                                             mu_tot,
+                         const gmx_vsite_t                               *vsite,
+                         const DDBalanceRegionHandler                    &ddBalanceRegionHandler);
 
 /* Print some final output */
 void done_shellfc(FILE *fplog, gmx_shellfc_t *shellfc, int64_t numSteps);
index 596fc8fa756502609fb1517ab61ffb4f98515fe0..857986d8147fbaa862b330394bb4344a48e342c8 100644 (file)
@@ -807,7 +807,7 @@ static void do_force_cutsVERLET(FILE *fplog,
                                 t_nrnb *nrnb,
                                 gmx_wallcycle_t wcycle,
                                 const gmx_localtop_t *top,
-                                const gmx_groups_t * /* groups */,
+                                const SimulationGroups * /* groups */,
                                 matrix box, gmx::ArrayRefWithPadding<gmx::RVec> x,
                                 history_t *hist,
                                 gmx::ArrayRefWithPadding<gmx::RVec> force,
@@ -1486,7 +1486,7 @@ static void do_force_cutsGROUP(FILE *fplog,
                                t_nrnb *nrnb,
                                gmx_wallcycle_t wcycle,
                                gmx_localtop_t *top,
-                               const gmx_groups_t *groups,
+                               const SimulationGroups *groups,
                                matrix box, gmx::ArrayRefWithPadding<gmx::RVec> x,
                                history_t *hist,
                                gmx::ArrayRefWithPadding<gmx::RVec> force,
@@ -1784,35 +1784,35 @@ static void do_force_cutsGROUP(FILE *fplog,
 
 }
 
-void do_force(FILE                                     *fplog,
-              const t_commrec                          *cr,
-              const gmx_multisim_t                     *ms,
-              const t_inputrec                         *inputrec,
-              gmx::Awh                                 *awh,
-              gmx_enfrot                               *enforcedRotation,
-              int64_t                                   step,
-              t_nrnb                                   *nrnb,
-              gmx_wallcycle_t                           wcycle,
-              gmx_localtop_t                           *top,
-              const gmx_groups_t                       *groups,
-              matrix                                    box,
-              gmx::ArrayRefWithPadding<gmx::RVec>       x,     //NOLINT(performance-unnecessary-value-param)
-              history_t                                *hist,
-              gmx::ArrayRefWithPadding<gmx::RVec>       force, //NOLINT(performance-unnecessary-value-param)
-              tensor                                    vir_force,
-              const t_mdatoms                          *mdatoms,
-              gmx_enerdata_t                           *enerd,
-              t_fcdata                                 *fcd,
-              gmx::ArrayRef<real>                       lambda,
-              t_graph                                  *graph,
-              t_forcerec                               *fr,
-              gmx::PpForceWorkload                     *ppForceWorkload,
-              const gmx_vsite_t                        *vsite,
-              rvec                                      mu_tot,
-              double                                    t,
-              gmx_edsam                                *ed,
-              int                                       flags,
-              const DDBalanceRegionHandler             &ddBalanceRegionHandler)
+void do_force(FILE                                            *fplog,
+              const t_commrec                                 *cr,
+              const gmx_multisim_t                            *ms,
+              const t_inputrec                                *inputrec,
+              gmx::Awh                                        *awh,
+              gmx_enfrot                                      *enforcedRotation,
+              int64_t                                          step,
+              t_nrnb                                          *nrnb,
+              gmx_wallcycle_t                                  wcycle,
+              gmx_localtop_t                                  *top,
+              const SimulationGroups                          *groups,
+              matrix                                           box,
+              gmx::ArrayRefWithPadding<gmx::RVec>              x,     //NOLINT(performance-unnecessary-value-param)
+              history_t                                       *hist,
+              gmx::ArrayRefWithPadding<gmx::RVec>              force, //NOLINT(performance-unnecessary-value-param)
+              tensor                                           vir_force,
+              const t_mdatoms                                 *mdatoms,
+              gmx_enerdata_t                                  *enerd,
+              t_fcdata                                        *fcd,
+              gmx::ArrayRef<real>                              lambda,
+              t_graph                                         *graph,
+              t_forcerec                                      *fr,
+              gmx::PpForceWorkload                            *ppForceWorkload,
+              const gmx_vsite_t                               *vsite,
+              rvec                                             mu_tot,
+              double                                           t,
+              gmx_edsam                                       *ed,
+              int                                              flags,
+              const DDBalanceRegionHandler                    &ddBalanceRegionHandler)
 {
     /* modify force flag if not doing nonbonded */
     if (!fr->bNonbonded)
index 1ec70fb65d2c9bae1246457ea2aab8996e7a9116..b3a5c80e943f39056b8e12897dbc07e80a32f2ad 100644 (file)
@@ -60,12 +60,12 @@ static void init_grpstat(const gmx_mtop_t *mtop, int ngacc, t_grp_acc gstat[])
 {
     if (ngacc > 0)
     {
-        const gmx_groups_t    &groups = mtop->groups;
+        const SimulationGroups    &groups = mtop->groups;
         for (const AtomProxy atomP : AtomRange(*mtop))
         {
             const t_atom &local = atomP.atom();
             int           i     = atomP.globalAtomNumber();
-            int           grp   = getGroupType(groups, egcACC, i);
+            int           grp   = getGroupType(groups, SimulationAtomGroupType::Acceleration, i);
             if ((grp < 0) && (grp >= ngacc))
             {
                 gmx_incons("Input for acceleration groups wrong");
index a2c33ecd9867e051ef7ebe193c5526651de5474f..4a5df16cf538b13df734d1f19115b60202ebadf4 100644 (file)
@@ -917,7 +917,7 @@ doSDUpdateGeneral(const gmx_stochd_t &sd,
                   const rvec x[], rvec xprime[], rvec v[], const rvec f[],
                   int64_t step, int seed, const int *gatindex)
 {
-    // cTC, cACC and cFreeze can be nullptr any time, but various
+    // cTC, cACC and cFREEZE can be nullptr any time, but various
     // instantiations do not make sense with particular pointer
     // values.
     if (updateType == SDUpdate::ForcesOnly)
index b0e8881668c14ca8923ef98fbd13fca0b5da30b1..c21afd2ec5f5d8c3d7e02f7c65700354b45a69b0 100644 (file)
@@ -54,7 +54,7 @@
 #include "gromacs/utility/gmxomp.h"
 #include "gromacs/utility/smalloc.h"
 
-t_vcm::t_vcm(const gmx_groups_t &groups, const t_inputrec &ir)
+t_vcm::t_vcm(const SimulationGroups &groups, const t_inputrec &ir)
 {
     mode     = (ir.nstcomm > 0) ? ir.comm_mode : ecmNO;
     ndim     = ndof_com(&ir);
@@ -68,7 +68,7 @@ t_vcm::t_vcm(const gmx_groups_t &groups, const t_inputrec &ir)
 
     if (mode != ecmNO)
     {
-        nr = groups.grps[egcVCM].nr;
+        nr = groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval].nr;
         /* Allocate one extra for a possible rest group */
         size = nr + 1;
         /* We need vcm->nr+1 elements per thread, but to avoid cache
@@ -93,7 +93,7 @@ t_vcm::t_vcm(const gmx_groups_t &groups, const t_inputrec &ir)
         for (int g = 0; (g < nr); g++)
         {
             group_ndf[g]  = ir.opts.nrdf[g];
-            group_name[g] = *groups.grpname[groups.grps[egcVCM].nm_ind[g]];
+            group_name[g] = *groups.groupNames[groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval].nm_ind[g]];
 
         }
 
index 8351d97e4ec8adfed79fdc4a1261bc33fb0e6098..b50d4b0ac59e38afef32c014c3cd32580bedc5bd 100644 (file)
@@ -46,7 +46,7 @@
 #include "gromacs/utility/basedefinitions.h"
 #include "gromacs/utility/real.h"
 
-struct gmx_groups_t;
+struct SimulationGroups;
 struct t_inputrec;
 struct t_mdatoms;
 
@@ -78,7 +78,7 @@ struct t_vcm
     ivec                     *nFreeze;    /* Tells whether dimensions are frozen per freeze group */
     std::vector<t_vcm_thread> thread_vcm; /* Temporary data per thread and group */
 
-    t_vcm(const gmx_groups_t &groups, const t_inputrec &ir);
+    t_vcm(const SimulationGroups &groups, const t_inputrec &ir);
     ~t_vcm();
 };
 
index 04bbd147113662aae0216221a086c567ca19c9af..3f086e6898a9367e5b7e32bedeb04b655294d79a 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2008, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, 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.
@@ -60,7 +60,7 @@
 
 void make_wall_tables(FILE *fplog,
                       const t_inputrec *ir, const char *tabfn,
-                      const gmx_groups_t *groups,
+                      const SimulationGroups *groups,
                       t_forcerec *fr)
 {
     int           negp_pp;
@@ -68,7 +68,7 @@ void make_wall_tables(FILE *fplog,
     char          buf[STRLEN];
 
     negp_pp = ir->opts.ngener - ir->nwall;
-    nm_ind  = groups->grps[egcENER].nm_ind;
+    nm_ind  = groups->groups[SimulationAtomGroupType::EnergyOutput].nm_ind;
 
     if (fplog)
     {
@@ -87,8 +87,8 @@ void make_wall_tables(FILE *fplog,
             {
                 sprintf(buf, "%s", tabfn);
                 sprintf(buf + strlen(tabfn) - strlen(ftp2ext(efXVG)) - 1, "_%s_%s.%s",
-                        *groups->grpname[nm_ind[egp]],
-                        *groups->grpname[nm_ind[negp_pp+w]],
+                        *groups->groupNames[nm_ind[egp]],
+                        *groups->groupNames[nm_ind[negp_pp+w]],
                         ftp2ext(efXVG));
                 fr->wall_tab[w][egp] = make_tables(fplog, fr->ic, buf, 0,
                                                    GMX_MAKETABLES_FORCEUSER);
index a706845e941fb34453f8c69222b6f71087d9c30a..1b9007ea2d1b6a0f261c41d967ace79ebcd05083 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2018, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019, 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.
@@ -39,7 +39,7 @@
 
 #include "gromacs/math/vectypes.h"
 
-struct gmx_groups_t;
+struct SimulationGroups;
 struct t_forcerec;
 struct t_idef;
 struct t_inputrec;
@@ -53,7 +53,7 @@ class ForceWithVirial;
 
 void make_wall_tables(FILE *fplog,
                       const t_inputrec *ir, const char *tabfn,
-                      const gmx_groups_t *groups,
+                      const SimulationGroups *groups,
                       t_forcerec *fr);
 
 real do_walls(const t_inputrec      &ir,
index 3aa48e5f728efbc8c854f4cd2991da3549f54741..13c2fadea6fb3f7c6ed9b86a305c3c6440c58cbb 100644 (file)
@@ -172,7 +172,6 @@ void gmx::Integrator::do_md()
     PaddedVector<gmx::RVec> f {};
     gmx_global_stat_t       gstat;
     t_graph                *graph = nullptr;
-    gmx_groups_t           *groups;
     gmx_shellfc_t          *shellfc;
     gmx_bool                bSumEkinhOld, bDoReplEx, bExchanged, bNeedRepartition;
     gmx_bool                bTemp, bPres, bTrotter;
@@ -231,7 +230,7 @@ void gmx::Integrator::do_md()
     nstglobalcomm   = check_nstglobalcomm(mdlog, nstglobalcomm, ir, cr);
     bGStatEveryStep = (nstglobalcomm == 1);
 
-    groups = &top_global->groups;
+    SimulationGroups                  *groups = &top_global->groups;
 
     std::unique_ptr<EssentialDynamics> ed = nullptr;
     if (opt2bSet("-ei", nfile, fnm) || observablesHistory->edsamHistory != nullptr)
@@ -272,7 +271,7 @@ void gmx::Integrator::do_md()
                                  ir->nstcalcenergy, DOMAINDECOMP(cr));
 
     {
-        double io = compute_io(ir, top_global->natoms, groups, energyOutput.numEnergyTerms(), 1);
+        double io = compute_io(ir, top_global->natoms, *groups, energyOutput.numEnergyTerms(), 1);
         if ((io > 2000) && MASTER(cr))
         {
             fprintf(stderr,
index 63f0fd259945437cd5587cdd669d6b962130dee7..b1549b7970a742562d5a23ed8f54dc8137085209 100644 (file)
@@ -153,7 +153,6 @@ void gmx::Integrator::do_mimic()
     PaddedVector<gmx::RVec>  f {};
     gmx_global_stat_t        gstat;
     t_graph                 *graph = nullptr;
-    gmx_groups_t            *groups;
     gmx_shellfc_t           *shellfc;
 
     double                   cycles;
@@ -222,7 +221,7 @@ void gmx::Integrator::do_mimic()
     }
 
     ir->nstxout_compressed                   = 0;
-    groups                                   = &top_global->groups;
+    SimulationGroups *groups                        = &top_global->groups;
     top_global->intermolecularExclusionGroup = genQmmmIndices(*top_global);
 
     initialize_lambdas(fplog, *ir, MASTER(cr), &state_global->fep_state, state_global->lambda, lam0);
@@ -247,7 +246,7 @@ void gmx::Integrator::do_mimic()
                                  ir->nstcalcenergy, DOMAINDECOMP(cr));
 
     {
-        double io = compute_io(ir, top_global->natoms, groups, energyOutput.numEnergyTerms(), 1);
+        double io = compute_io(ir, top_global->natoms, *groups, energyOutput.numEnergyTerms(), 1);
         if ((io > 2000) && MASTER(cr))
         {
             fprintf(stderr,
index b346359573463df6a5fa60aba08f273ce408ec41..039c3bddfd4ed47beb12f603d2b3c578e7969de6 100644 (file)
@@ -920,14 +920,13 @@ EnergyEvaluator::run(em_state_t *ems, rvec mu_tot,
 } // namespace
 
 //! Parallel utility summing energies and forces
-static double reorder_partsum(const t_commrec *cr, t_grpopts *opts, t_mdatoms *mdatoms,
+static double reorder_partsum(const t_commrec *cr, t_grpopts *opts,
                               gmx_mtop_t *top_global,
                               em_state_t *s_min, em_state_t *s_b)
 {
     t_block       *cgs_gl;
     int            ncg, *cg_gl, *index, c, cg, i, a0, a1, a, gf, m;
     double         partsum;
-    unsigned char *grpnrFREEZE;
 
     if (debug)
     {
@@ -969,7 +968,7 @@ static double reorder_partsum(const t_commrec *cr, t_grpopts *opts, t_mdatoms *m
     partsum     = 0;
     i           = 0;
     gf          = 0;
-    grpnrFREEZE = top_global->groups.grpnr[egcFREEZE];
+    gmx::ArrayRef<unsigned char> grpnrFREEZE = top_global->groups.groupNumbers[SimulationAtomGroupType::Freeze];
     for (c = 0; c < ncg; c++)
     {
         cg = cg_gl[c];
@@ -977,7 +976,7 @@ static double reorder_partsum(const t_commrec *cr, t_grpopts *opts, t_mdatoms *m
         a1 = index[cg+1];
         for (a = a0; a < a1; a++)
         {
-            if (mdatoms->cFREEZE && grpnrFREEZE)
+            if (!grpnrFREEZE.empty())
             {
                 gf = grpnrFREEZE[i];
             }
@@ -1038,7 +1037,7 @@ static real pr_beta(const t_commrec *cr, t_grpopts *opts, t_mdatoms *mdatoms,
     else
     {
         /* We need to reorder cgs while summing */
-        sum = reorder_partsum(cr, opts, mdatoms, top_global, s_min, s_b);
+        sum = reorder_partsum(cr, opts, top_global, s_min, s_b);
     }
     if (PAR(cr))
     {
index e6c15799fa0ee3e3ca13da28b4f479ca8bc2ec32..61999f570ad6ca92fef51785c05e3714a2d64bf1 100644 (file)
@@ -207,7 +207,6 @@ void gmx::Integrator::do_rerun()
     PaddedVector<gmx::RVec> f {};
     gmx_global_stat_t       gstat;
     t_graph                *graph = nullptr;
-    gmx_groups_t           *groups;
     gmx_shellfc_t          *shellfc;
 
     double                  cycles;
@@ -291,7 +290,7 @@ void gmx::Integrator::do_rerun()
     const bool bNS           = true;
 
     ir->nstxout_compressed = 0;
-    groups                 = &top_global->groups;
+    SimulationGroups *groups                 = &top_global->groups;
     if (ir->eI == eiMimic)
     {
         top_global->intermolecularExclusionGroup = genQmmmIndices(*top_global);
@@ -318,7 +317,7 @@ void gmx::Integrator::do_rerun()
                                  ir->nstcalcenergy, DOMAINDECOMP(cr));
 
     {
-        double io = compute_io(ir, top_global->natoms, groups, energyOutput.numEnergyTerms(), 1);
+        double io = compute_io(ir, top_global->natoms, *groups, energyOutput.numEnergyTerms(), 1);
         if ((io > 2000) && MASTER(cr))
         {
             fprintf(stderr,
index f8b5ebd151b7d3ea8ec7206c48467c134c2a42e9..5585d25bb83dfe09f0575c0c01e5a3f60b382398 100644 (file)
@@ -1506,7 +1506,7 @@ int Mdrunner::mdrunner()
         /* Energy terms and groups */
         gmx_enerdata_t *enerd;
         snew(enerd, 1);
-        init_enerdata(mtop.groups.grps[egcENER].nr, inputrec->fepvals->n_lambda, enerd);
+        init_enerdata(mtop.groups.groups[SimulationAtomGroupType::EnergyOutput].nr, inputrec->fepvals->n_lambda, enerd);
 
         if (DOMAINDECOMP(cr))
         {
@@ -1598,7 +1598,7 @@ int Mdrunner::mdrunner()
     free_gpu_resources(fr, physicalNodeComm);
     free_gpu(nonbondedDeviceInfo);
     free_gpu(pmeDeviceInfo);
-    done_forcerec(fr, mtop.molblock.size(), mtop.groups.grps[egcENER].nr);
+    done_forcerec(fr, mtop.molblock.size(), mtop.groups.groups[SimulationAtomGroupType::EnergyOutput].nr);
     sfree(fcd);
 
     if (doMembed)
index 71f79e5d1f1157374441cfcb01a9c754ce461f24..d13a84860923d541af52df6d876cedc9d0080174 100644 (file)
@@ -137,7 +137,6 @@ void
 Integrator::do_tpi()
 {
     gmx_localtop_t          top;
-    gmx_groups_t           *groups;
     PaddedVector<gmx::RVec> f {};
     real                    lambda, t, temp, beta, drmax, epot;
     double                  embU, sum_embU, *sum_UgembU, V, V_all, VembU_all;
@@ -188,7 +187,7 @@ Integrator::do_tpi()
 
     gmx_mtop_generate_local_top(*top_global, &top, inputrec->efep != efepNO);
 
-    groups = &top_global->groups;
+    SimulationGroups *groups = &top_global->groups;
 
     bCavity = (inputrec->eI == eiTPIC);
     if (bCavity)
@@ -347,7 +346,7 @@ Integrator::do_tpi()
         }
     }
 
-    ngid   = groups->grps[egcENER].nr;
+    ngid   = groups->groups[SimulationAtomGroupType::EnergyOutput].nr;
     gid_tp = GET_CGINFO_GID(fr->cginfo[cg_tp]);
     nener  = 1 + ngid;
     if (bDispCorr)
@@ -395,7 +394,7 @@ Integrator::do_tpi()
         for (i = 0; i < ngid; i++)
         {
             sprintf(str, "f. <U\\sVdW %s\\Ne\\S-\\betaU\\N>",
-                    *(groups->grpname[groups->grps[egcENER].nm_ind[i]]));
+                    *(groups->groupNames[groups->groups[SimulationAtomGroupType::EnergyOutput].nm_ind[i]]));
             leg[e++] = gmx_strdup(str);
         }
         if (bDispCorr)
@@ -408,7 +407,7 @@ Integrator::do_tpi()
             for (i = 0; i < ngid; i++)
             {
                 sprintf(str, "f. <U\\sCoul %s\\Ne\\S-\\betaU\\N>",
-                        *(groups->grpname[groups->grps[egcENER].nm_ind[i]]));
+                        *(groups->groupNames[groups->groups[SimulationAtomGroupType::EnergyOutput].nm_ind[i]]));
                 leg[e++] = gmx_strdup(str);
             }
             if (bRFExcl)
index b16480a14e2d8f56328ae0b8e0b255e831e38b95..eaf6b4c136551cd8fc60b72389743d3c45d49210 100644 (file)
@@ -41,9 +41,9 @@
 
 std::vector<int> genQmmmIndices(const gmx_mtop_t &mtop)
 {
-    std::vector<int> output;
-    int              global_at = 0;
-    unsigned char   *grpnr     = mtop.groups.grpnr[egcQMMM];
+    std::vector<int>       output;
+    int                    global_at = 0;
+    const unsigned char   *grpnr     = mtop.groups.groupNumbers[SimulationAtomGroupType::QuantumMechanics].data();
     for (const gmx_molblock_t &molb : mtop.molblock)
     {
         for (int mol = 0; mol < molb.nmol; ++mol)
index 54ba106a6296e8d250900af33a58dfcadd4daaa3..e0ec906652589c266e496494f9eb069dd5c5e8d0 100644 (file)
@@ -1728,9 +1728,9 @@ static void init_pull_group_index(FILE *fplog, const t_commrec *cr,
                              ir->eI == eiBD);
 
     /* In parallel, store we need to extract localWeights from weights at DD time */
-    std::vector<real>  &weights = ((cr && PAR(cr)) ? pg->globalWeights : pg->localWeights);
+    std::vector<real>         &weights = ((cr && PAR(cr)) ? pg->globalWeights : pg->localWeights);
 
-    const gmx_groups_t &groups  = mtop->groups;
+    const SimulationGroups    &groups  = mtop->groups;
 
     /* Count frozen dimensions and (weighted) mass */
     int    nfrozen = 0;
@@ -1746,7 +1746,7 @@ static void init_pull_group_index(FILE *fplog, const t_commrec *cr,
             for (int d = 0; d < DIM; d++)
             {
                 if (pulldim_con[d] == 1 &&
-                    ir->opts.nFreeze[getGroupType(groups, egcFREEZE, ii)][d])
+                    ir->opts.nFreeze[getGroupType(groups, SimulationAtomGroupType::Freeze, ii)][d])
                 {
                     nfrozen++;
                 }
@@ -1786,13 +1786,13 @@ static void init_pull_group_index(FILE *fplog, const t_commrec *cr,
             }
             else
             {
-                if (groups.grpnr[egcTC] == nullptr)
+                if (groups.groupNumbers[SimulationAtomGroupType::TemperatureCoupling].empty())
                 {
                     mbd = ir->delta_t/ir->opts.tau_t[0];
                 }
                 else
                 {
-                    mbd = ir->delta_t/ir->opts.tau_t[groups.grpnr[egcTC][ii]];
+                    mbd = ir->delta_t/ir->opts.tau_t[groups.groupNumbers[SimulationAtomGroupType::TemperatureCoupling][ii]];
                 }
             }
             w                   *= m/mbd;
index b116ff6d0549985c59836ab9a41fd4a4b45c77ea..4b648826cafb0c0950a57785ebe6b43f90b9871f 100644 (file)
@@ -96,7 +96,7 @@ void list_tpr(const char *fn,
               gmx_bool    bOriginalInputrec)
 {
     FILE         *gp;
-    int           indent, i, j, **gcount, atot;
+    int           indent, atot;
     t_state       state;
     t_tpxheader   tpx;
     gmx_mtop_t    mtop;
@@ -158,35 +158,33 @@ void list_tpr(const char *fn,
             pr_rvecs(stdout, indent, "v", tpx.bV ? state.v.rvec_array() : nullptr, state.natoms);
         }
 
-        const gmx_groups_t &groups = mtop.groups;
+        const SimulationGroups &groups = mtop.groups;
 
-        snew(gcount, egcNR);
-        for (i = 0; (i < egcNR); i++)
+        gmx::EnumerationArray < SimulationAtomGroupType, std::vector < int>> gcount;
+        for (auto group : keysOf(gcount))
         {
-            snew(gcount[i], groups.grps[i].nr);
+            gcount[group].resize(groups.groups[group].nr);
         }
 
-        for (i = 0; (i < mtop.natoms); i++)
+        for (int i = 0; (i < mtop.natoms); i++)
         {
-            for (j = 0; (j < egcNR); j++)
+            for (auto group : keysOf(gcount))
             {
-                gcount[j][getGroupType(groups, j, i)]++;
+                gcount[group][getGroupType(groups, group, i)]++;
             }
         }
         printf("Group statistics\n");
-        for (i = 0; (i < egcNR); i++)
+        for (auto group : keysOf(gcount))
         {
             atot = 0;
-            printf("%-12s: ", gtypes[i]);
-            for (j = 0; (j < groups.grps[i].nr); j++)
+            printf("%-12s: ", shortName(group));
+            for (int j = 0; (j < groups.groups[group].nr); j++)
             {
-                printf("  %5d", gcount[i][j]);
-                atot += gcount[i][j];
+                printf("  %5d", gcount[group][j]);
+                atot += gcount[group][j];
             }
             printf("  (total %d atoms)\n", atot);
-            sfree(gcount[i]);
         }
-        sfree(gcount);
     }
 }
 
index 6e621644fc049a02f1fa4a8ff8065bb9c99599cc..52681315d3c1a1a1fea3d6a585c0ffcf7904a009 100644 (file)
 #include "gromacs/utility/strconvert.h"
 #include "gromacs/utility/txtdump.h"
 
-const char *gtypes[egcNR+1] = {
-    "T-Coupling", "Energy Mon.", "Acceleration", "Freeze",
-    "User1", "User2", "VCM", "Compressed X", "Or. Res. Fit", "QMMM", nullptr
-};
+gmx::EnumerationArray<SimulationAtomGroupType, const char *>
+c_simulationAtomGroupTypeShortNames
+    = { {
+            "T-Coupling",
+            "Energy Mon.",
+            "Acceleration",
+            "Freeze",
+            "User1",
+            "User2",
+            "VCM",
+            "Compressed X",
+            "Or. Res. Fit",
+            "QMMM"
+        } };
 
-static void init_groups(gmx_groups_t *groups)
+const char *shortName(SimulationAtomGroupType type)
 {
-    groups->ngrpname = 0;
-    groups->grpname  = nullptr;
-    for (int g = 0; g < egcNR; g++)
+    return c_simulationAtomGroupTypeShortNames[type];
+}
+
+SimulationGroups::SimulationGroups()
+{
+    for (auto group : keysOf(groups))
     {
-        groups->grps[g].nr     = 0;
-        groups->grps[g].nm_ind = nullptr;
-        groups->ngrpnr[g]      = 0;
-        groups->grpnr[g]       = nullptr;
+        groups[group].nr     = 0;
+        groups[group].nm_ind = nullptr;
     }
 
 }
@@ -101,31 +112,21 @@ gmx_moltype_t::~gmx_moltype_t()
     done_blocka(&excls);
 }
 
-void done_gmx_groups_t(gmx_groups_t *g)
+SimulationGroups::~SimulationGroups()
 {
-    int i;
-
-    for (i = 0; (i < egcNR); i++)
+    for (auto group : keysOf(groups))
     {
-        if (nullptr != g->grps[i].nm_ind)
+        if (nullptr != groups[group].nm_ind)
         {
-            sfree(g->grps[i].nm_ind);
-            g->grps[i].nm_ind = nullptr;
-        }
-        if (nullptr != g->grpnr[i])
-        {
-            sfree(g->grpnr[i]);
-            g->grpnr[i] = nullptr;
+            sfree(groups[group].nm_ind);
+            groups[group].nm_ind = nullptr;
         }
     }
-    /* The contents of this array is in symtab, don't free it here */
-    sfree(g->grpname);
 }
 
 gmx_mtop_t::gmx_mtop_t()
 {
     init_atomtypes(&atomtypes);
-    init_groups(&groups);
     open_symtab(&symtab);
 }
 
@@ -136,7 +137,6 @@ gmx_mtop_t::~gmx_mtop_t()
     moltype.clear();
     molblock.clear();
     done_atomtypes(&atomtypes);
-    done_gmx_groups_t(&groups);
 }
 
 void done_top(t_topology *top)
@@ -247,45 +247,49 @@ bool gmx_mtop_has_pdbinfo(const gmx_mtop_t *mtop)
     return mtop->moltype.empty() || mtop->moltype[0].atoms.havePdbInfo;
 }
 
-static void pr_grps(FILE *fp, const char *title, const t_grps grps[], char **grpname[])
+static void pr_grps(FILE                       *fp,
+                    const char                 *title,
+                    gmx::ArrayRef<const t_grps> grps,
+                    char                     ***grpname)
 {
-    int i, j;
-
-    for (i = 0; (i < egcNR); i++)
+    int index = 0;
+    for (const auto &group : grps)
     {
-        fprintf(fp, "%s[%-12s] nr=%d, name=[", title, gtypes[i], grps[i].nr);
-        for (j = 0; (j < grps[i].nr); j++)
+        fprintf(fp, "%s[%-12s] nr=%d, name=[", title, c_simulationAtomGroupTypeShortNames[index], group.nr);
+        for (int j = 0; (j < group.nr); j++)
         {
-            fprintf(fp, " %s", *(grpname[grps[i].nm_ind[j]]));
+            fprintf(fp, " %s", *(grpname[group.nm_ind[j]]));
         }
         fprintf(fp, "]\n");
+        index++;
     }
 }
 
 static void pr_groups(FILE *fp, int indent,
-                      const gmx_groups_t *groups,
+                      const SimulationGroups &groups,
                       gmx_bool bShowNumbers)
 {
-    int nat_max, i, g;
-
-    pr_grps(fp, "grp", groups->grps, groups->grpname);
-    pr_strings(fp, indent, "grpname", groups->grpname, groups->ngrpname, bShowNumbers);
+    pr_grps(fp,
+            "grp",
+            groups.groups,
+            const_cast<char ***>(groups.groupNames.data()));
+    pr_strings(fp, indent, "grpname", const_cast<char ***>(groups.groupNames.data()), groups.groupNames.size(), bShowNumbers);
 
     pr_indent(fp, indent);
     fprintf(fp, "groups          ");
-    for (g = 0; g < egcNR; g++)
+    for (const auto &group : c_simulationAtomGroupTypeShortNames)
     {
-        printf(" %5.5s", gtypes[g]);
+        printf(" %5.5s", group);
     }
     printf("\n");
 
     pr_indent(fp, indent);
     fprintf(fp, "allocated       ");
-    nat_max = 0;
-    for (g = 0; g < egcNR; g++)
+    int nat_max = 0;
+    for (auto group : keysOf(groups.groups))
     {
-        printf(" %5d", groups->ngrpnr[g]);
-        nat_max = std::max(nat_max, groups->ngrpnr[g]);
+        printf(" %5d", groups.numberOfGroupNumbers(group));
+        nat_max = std::max(nat_max, groups.numberOfGroupNumbers(group));
     }
     printf("\n");
 
@@ -293,7 +297,7 @@ static void pr_groups(FILE *fp, int indent,
     {
         pr_indent(fp, indent);
         fprintf(fp, "groupnr[%5s] =", "*");
-        for (g = 0; g < egcNR; g++)
+        for (auto gmx_unused group : keysOf(groups.groups))
         {
             fprintf(fp, "  %3d ", 0);
         }
@@ -301,14 +305,15 @@ static void pr_groups(FILE *fp, int indent,
     }
     else
     {
-        for (i = 0; i < nat_max; i++)
+        for (int i = 0; i < nat_max; i++)
         {
             pr_indent(fp, indent);
             fprintf(fp, "groupnr[%5d] =", i);
-            for (g = 0; g < egcNR; g++)
+            for (auto group : keysOf(groups.groups))
             {
                 fprintf(fp, "  %3d ",
-                        groups->grpnr[g] ? groups->grpnr[g][i] : 0);
+                        !groups.groupNumbers[group].empty() ?
+                        groups.groupNumbers[group][i] : 0);
             }
             fprintf(fp, "\n");
         }
@@ -390,7 +395,7 @@ void pr_mtop(FILE *fp, int indent, const char *title, const gmx_mtop_t *mtop,
             pr_moltype(fp, indent, "moltype", &mtop->moltype[mt], mt,
                        &mtop->ffparams, bShowNumbers, bShowParameters);
         }
-        pr_groups(fp, indent, &mtop->groups, bShowNumbers);
+        pr_groups(fp, indent, mtop->groups, bShowNumbers);
     }
 }
 
@@ -667,32 +672,32 @@ void compareMtopAB(FILE *fp, const gmx_mtop_t &mtop1, real relativeTolerance, re
     compareMoletypeAB(fp, mtop1.moltype, relativeTolerance, absoluteTolerance);
 }
 
-void compareAtomGroups(FILE *fp, const gmx_groups_t &g0, const gmx_groups_t &g1,
+void compareAtomGroups(FILE *fp, const SimulationGroups &g0, const SimulationGroups &g1,
                        int natoms0, int natoms1)
 {
     fprintf(fp, "comparing groups\n");
 
-    for (int i = 0; i < egcNR; i++)
+    for (auto group : keysOf(g0.groups))
     {
-        std::string buf = gmx::formatString("grps[%d].nr", i);
-        cmp_int(fp, buf.c_str(), -1, g0.grps[i].nr, g1.grps[i].nr);
-        if (g0.grps[i].nr == g1.grps[i].nr)
+        std::string buf = gmx::formatString("grps[%d].nr", static_cast<int>(group));
+        cmp_int(fp, buf.c_str(), -1, g0.groups[group].nr, g1.groups[group].nr);
+        if (g0.groups[group].nr == g1.groups[group].nr)
         {
-            for (int j = 0; j < g0.grps[i].nr; j++)
+            for (int j = 0; j < g0.groups[group].nr; j++)
             {
-                buf = gmx::formatString("grps[%d].name[%d]", i, j);
+                buf = gmx::formatString("grps[%d].name[%d]", static_cast<int>(group), j);
                 cmp_str(fp, buf.c_str(), -1,
-                        *g0.grpname[g0.grps[i].nm_ind[j]],
-                        *g1.grpname[g1.grps[i].nm_ind[j]]);
+                        *g0.groupNames[g0.groups[group].nm_ind[j]],
+                        *g1.groupNames[g1.groups[group].nm_ind[j]]);
             }
         }
-        cmp_int(fp, "ngrpnr", i, g0.ngrpnr[i], g1.ngrpnr[i]);
-        if (g0.ngrpnr[i] == g1.ngrpnr[i] && natoms0 == natoms1 &&
-            (g0.grpnr[i] != nullptr || g1.grpnr[i] != nullptr))
+        cmp_int(fp, "ngrpnr", static_cast<int>(group), g0.numberOfGroupNumbers(group), g1.numberOfGroupNumbers(group));
+        if (g0.numberOfGroupNumbers(group) == g1.numberOfGroupNumbers(group) && natoms0 == natoms1 &&
+            (!g0.groupNumbers[group].empty() || !g1.groupNumbers[group].empty()))
         {
             for (int j = 0; j < natoms0; j++)
             {
-                cmp_int(fp, gtypes[i], j, getGroupType(g0, i, j), getGroupType(g1, i, j));
+                cmp_int(fp, c_simulationAtomGroupTypeShortNames[group], j, getGroupType(g0, group, j), getGroupType(g1, group, j));
             }
         }
     }
@@ -701,9 +706,9 @@ void compareAtomGroups(FILE *fp, const gmx_groups_t &g0, const gmx_groups_t &g1,
      */
 }
 
-int getGroupType(const gmx_groups_t &group, int type, int atom)
+int getGroupType(const SimulationGroups &group, SimulationAtomGroupType type, int atom)
 {
-    return (group.grpnr[type] ? group.grpnr[type][atom] : 0);
+    return (group.groupNumbers[type].empty() ? 0 : group.groupNumbers[type][atom]);
 }
 
 void copy_moltype(const gmx_moltype_t *src, gmx_moltype_t *dst)
index 87ee01aefad346a27315489cf9b837f7c12afde7..f33727fa3f3b653b5412c3bf5ee5bd2631c5ceba 100644 (file)
 #include "gromacs/topology/forcefieldparameters.h"
 #include "gromacs/topology/idef.h"
 #include "gromacs/topology/symtab.h"
+#include "gromacs/utility/enumerationhelpers.h"
 #include "gromacs/utility/unique_cptr.h"
 
-enum
+enum class SimulationAtomGroupType : int
 {
-    egcTC,    egcENER,   egcACC, egcFREEZE,
-    egcUser1, egcUser2,  egcVCM, egcCompressedX,
-    egcORFIT, egcQMMM,
-    egcNR
+    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
@@ -99,14 +110,31 @@ struct MoleculeBlockIndices
     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;
+    SimulationGroups();
+
+    ~SimulationGroups();
+
+    //! Groups of particles
+    gmx::EnumerationArray<SimulationAtomGroupType, t_grps>                     groups;
+    //! Names of groups, stored as pointer to the entries in the symbol table.
+    std::vector<char **>                                                       groupNames;
+    //! Group numbers for the different SimulationAtomGroupType groups.
+    gmx::EnumerationArray < SimulationAtomGroupType, std::vector < unsigned char>> groupNumbers;
+
+    /*! \brief
+     * Number of group numbers for a single SimulationGroup.
+     *
+     * \param[in] group Integer value for the group type.
+     */
+    int numberOfGroupNumbers(SimulationAtomGroupType group) const { return groupNumbers[group].size(); }
+};
 
 /*! \brief
  * Returns group number of an input group for a given atom.
@@ -118,7 +146,7 @@ typedef struct gmx_groups_t
  * \param[in] type  Type of group to check.
  * \param[in] atom  Atom to check if it has an entry.
  */
-int getGroupType (const gmx_groups_t &group, int type, int atom);
+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.
@@ -146,21 +174,21 @@ struct gmx_mtop_t //NOLINT(clang-analyzer-optin.performance.Padding)
      * List of intermolecular interactions using system wide
      * atom indices, either NULL or size F_NRE
      */
-    std::unique_ptr<InteractionLists> intermolecular_ilist = nullptr;
+    std::unique_ptr<InteractionLists>        intermolecular_ilist = nullptr;
     //! Number of global atoms.
-    int                               natoms = 0;
+    int                                      natoms = 0;
     //! Parameter for residue numbering.
-    int                               maxres_renum = 0;
+    int                                      maxres_renum = 0;
     //! The maximum residue number in moltype
-    int                               maxresnr = -1;
+    int                                      maxresnr = -1;
     //! Atomtype properties
-    t_atomtypes                       atomtypes;
+    t_atomtypes                              atomtypes;
     //! Groups of atoms for different purposes
-    gmx_groups_t                      groups;
+    SimulationGroups                         groups;
     //! The symbol table
-    t_symtab                          symtab;
+    t_symtab                                 symtab;
     //! Tells whether we have valid molecule indices
-    bool                              haveMoleculeIndices = false;
+    bool                                     haveMoleculeIndices = false;
     /*! \brief List of global atom indices of atoms between which
      * non-bonded interactions must be excluded.
      */
@@ -171,7 +199,7 @@ struct gmx_mtop_t //NOLINT(clang-analyzer-optin.performance.Padding)
     std::vector<MoleculeBlockIndices> moleculeBlockIndices;
 };
 
-/* \brief
+/*! \brief
  * The fully written out topology for a domain over its lifetime
  *
  * Also used in some analysis code.
@@ -210,7 +238,6 @@ typedef struct t_topology
 } t_topology;
 
 void init_top(t_topology *top);
-void done_gmx_groups_t(gmx_groups_t *g);
 void done_top(t_topology *top);
 // Frees both t_topology and gmx_mtop_t when the former has been created from
 // the latter.
@@ -254,7 +281,7 @@ void compareMtopAB(FILE *fp, const gmx_mtop_t &mtop1, real relativeTolerance, re
  * \param[in] natoms0 Number of atoms for first group.
  * \param[in] natoms1 Number of atoms for second group.
  */
-void compareAtomGroups(FILE *fp, const gmx_groups_t &g0, const gmx_groups_t &g1,
+void compareAtomGroups(FILE *fp, const SimulationGroups &g0, const SimulationGroups &g1,
                        int natoms0, int natoms1);
 
 //! Typedef for gmx_localtop in analysis tools.
index 1b15b334f6da5d1116ae68b594b686d493ffbd99..404529c3c48ac52b983c6f370fb52e5f89a25267 100644 (file)
@@ -1,7 +1,7 @@
 #
 # This file is part of the GROMACS molecular simulation package.
 #
-# Copyright (c) 2010,2011,2012,2013,2014,2015,2017,2018, by the GROMACS development team, led by
+# Copyright (c) 2010,2011,2012,2013,2014,2015,2017,2018,2019, 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.
@@ -49,6 +49,7 @@ gmx_install_headers(
     cstringutil.h
     current_function.h
     datafilefinder.h
+    enumerationhelpers.h
     errorcodes.h
     exceptions.h
     fatalerror.h
index 71a84c18dec4928f46f9f8ea82fcea47883460e3..49ecd98d9c0c2da0039dabfb32cb71400d2336eb 100644 (file)
@@ -32,8 +32,7 @@
  * To help us fund GROMACS development, we humbly ask that you cite
  * the research papers on the package. Check out http://www.gromacs.org.
  */
-/*! \libinternal
- * \file
+/*! \file
  * \brief Defines helper types for class enumerations.
  *
  * These helper types facilitate iterating over class enums, and
@@ -294,6 +293,8 @@ struct EnumerationArray final
 
     //! Returns a const raw pointer to the contents of the array.
     const_pointer data() const { return &m_elements[0]; }
+    //! Returns a raw pointer to the contents of the array.
+    pointer data() { return &m_elements[0]; }
 };
 
 /*! \brief Returns an object that provides iterators over the keys