Replace gmx_mtop_ilistloop_all
authorPaul Bauer <paul.bauer.q@gmail.com>
Fri, 2 Apr 2021 15:58:10 +0000 (15:58 +0000)
committerArtem Zhmurov <zhmurov@gmail.com>
Fri, 2 Apr 2021 15:58:10 +0000 (15:58 +0000)
src/gromacs/domdec/domdec.cpp
src/gromacs/fileio/tpxio.cpp
src/gromacs/gmxpreprocess/readir.cpp
src/gromacs/listed_forces/disre.cpp
src/gromacs/listed_forces/orires.cpp
src/gromacs/mdlib/settle.cpp
src/gromacs/topology/mtop_util.cpp
src/gromacs/topology/mtop_util.h

index 5b431017bc13c9ebf25ebd2bb0b95a9a876217f6..d941620c1214fe3b8caf0e6a674977c975eee478 100644 (file)
@@ -1707,16 +1707,14 @@ static real* get_slb_frac(const gmx::MDLogger& mdlog, const char* dir, int nc, c
 
 static int multi_body_bondeds_count(const gmx_mtop_t& mtop)
 {
-    int                  n     = 0;
-    gmx_mtop_ilistloop_t iloop = gmx_mtop_ilistloop_init(mtop);
-    int                  nmol  = 0;
-    while (const InteractionLists* ilists = gmx_mtop_ilistloop_next(iloop, &nmol))
+    int n = 0;
+    for (const auto ilists : IListRange(mtop))
     {
-        for (auto& ilist : extractILists(*ilists, IF_BOND))
+        for (auto& ilist : extractILists(ilists.list(), IF_BOND))
         {
             if (NRAL(ilist.functionType) > 2)
             {
-                n += nmol * (ilist.iatoms.size() / ilistStride(ilist));
+                n += ilists.nmol() * (ilist.iatoms.size() / ilistStride(ilist));
             }
         }
     }
@@ -1914,16 +1912,13 @@ static gmx_domdec_comm_t* init_dd_comm()
 /* Returns whether mtop contains constraints and/or vsites */
 static bool systemHasConstraintsOrVsites(const gmx_mtop_t& mtop)
 {
-    auto* ilistLoop = gmx_mtop_ilistloop_init(mtop);
-    int   nmol      = 0;
-    while (const InteractionLists* ilists = gmx_mtop_ilistloop_next(ilistLoop, &nmol))
+    for (const auto ilists : IListRange(mtop))
     {
-        if (!extractILists(*ilists, IF_CONSTRAINT | IF_VSITE).empty())
+        if (!extractILists(ilists.list(), IF_CONSTRAINT | IF_VSITE).empty())
         {
             return true;
         }
     }
-
     return false;
 }
 
index 4bcf3256d6289892de1bd88546ed06c55093f13b..74527a75813cd9a9146ac948f5590b865a33b6e6 100644 (file)
@@ -2533,15 +2533,11 @@ static void do_molblock(gmx::ISerializer* serializer, gmx_molblock_t* molb, int
 
 static void set_disres_npair(gmx_mtop_t* mtop)
 {
-    gmx_mtop_ilistloop_t iloop;
-    int                  nmol;
-
     gmx::ArrayRef<t_iparams> ip = mtop->ffparams.iparams;
 
-    iloop = gmx_mtop_ilistloop_init(*mtop);
-    while (const InteractionLists* ilist = gmx_mtop_ilistloop_next(iloop, &nmol))
+    for (const auto ilist : IListRange(*mtop))
     {
-        const InteractionList& il = (*ilist)[F_DISRES];
+        const InteractionList& il = ilist.list()[F_DISRES];
 
         if (!il.empty())
         {
index 2c0e08c4feef01a5307049ccbcbb18428d12aff4..426bd68d395cacee44352768bd158adcb522cf6f 100644 (file)
@@ -4111,10 +4111,8 @@ static void check_disre(const gmx_mtop_t& mtop)
 
 static bool absolute_reference(const t_inputrec* ir, const gmx_mtop_t& sys, const bool posres_only, ivec AbsRef)
 {
-    int                  d, g, i;
-    gmx_mtop_ilistloop_t iloop;
-    int                  nmol;
-    const t_iparams*     pr;
+    int              d, g, i;
+    const t_iparams* pr;
 
     clear_ivec(AbsRef);
 
@@ -4139,14 +4137,13 @@ static bool absolute_reference(const t_inputrec* ir, const gmx_mtop_t& sys, cons
     }
 
     /* Check for position restraints */
-    iloop = gmx_mtop_ilistloop_init(sys);
-    while (const InteractionLists* ilist = gmx_mtop_ilistloop_next(iloop, &nmol))
+    for (const auto ilist : IListRange(sys))
     {
-        if (nmol > 0 && (AbsRef[XX] == 0 || AbsRef[YY] == 0 || AbsRef[ZZ] == 0))
+        if (ilist.nmol() > 0 && (AbsRef[XX] == 0 || AbsRef[YY] == 0 || AbsRef[ZZ] == 0))
         {
-            for (i = 0; i < (*ilist)[F_POSRES].size(); i += 2)
+            for (int i = 0; i < ilist.list()[F_POSRES].size(); i += 2)
             {
-                pr = &sys.ffparams.iparams[(*ilist)[F_POSRES].iatoms[i]];
+                pr = &sys.ffparams.iparams[ilist.list()[F_POSRES].iatoms[i]];
                 for (d = 0; d < DIM; d++)
                 {
                     if (pr->posres.fcA[d] != 0)
@@ -4155,10 +4152,10 @@ static bool absolute_reference(const t_inputrec* ir, const gmx_mtop_t& sys, cons
                     }
                 }
             }
-            for (i = 0; i < (*ilist)[F_FBPOSRES].size(); i += 2)
+            for (i = 0; i < ilist.list()[F_FBPOSRES].size(); i += 2)
             {
                 /* Check for flat-bottom posres */
-                pr = &sys.ffparams.iparams[(*ilist)[F_FBPOSRES].iatoms[i]];
+                pr = &sys.ffparams.iparams[ilist.list()[F_FBPOSRES].iatoms[i]];
                 if (pr->fbposres.k != 0)
                 {
                     switch (pr->fbposres.geom)
index 8a901875c78e4742b3d72dbdfb5863f8f08479d4..de1928792ab0c244f454f50b32f613e7546f2782 100644 (file)
@@ -81,11 +81,9 @@ void init_disres(FILE*                 fplog,
                  t_state*              state,
                  gmx_bool              bIsREMD)
 {
-    int                  fa, nmol, npair, np;
-    history_t*           hist;
-    gmx_mtop_ilistloop_t iloop;
-    char*                ptr;
-    int                  type_min, type_max;
+    history_t* hist;
+    char*      ptr;
+    int        type_min, type_max;
 
     if (gmx_mtop_ftype_count(mtop, F_DISRES) == 0)
     {
@@ -137,10 +135,10 @@ void init_disres(FILE*                 fplog,
     dd->npair = 0;
     type_min  = INT_MAX;
     type_max  = 0;
-    iloop     = gmx_mtop_ilistloop_init(mtop);
-    while (const InteractionLists* il = gmx_mtop_ilistloop_next(iloop, &nmol))
+    for (const auto il : IListRange(mtop))
     {
-        if (nmol > 1 && !(*il)[F_DISRES].empty() && ir->eDisre != DistanceRestraintRefinement::Ensemble)
+        if (il.nmol() > 1 && !il.list()[F_DISRES].empty()
+            && ir->eDisre != DistanceRestraintRefinement::Ensemble)
         {
             gmx_fatal(FARGS,
                       "NMR distance restraints with multiple copies of the same molecule are "
@@ -149,19 +147,17 @@ void init_disres(FILE*                 fplog,
                       "a restraint potential (bonds type 10) instead.");
         }
 
-        np = 0;
-        for (fa = 0; fa < (*il)[F_DISRES].size(); fa += 3)
+        int np = 0;
+        for (int fa = 0; fa < il.list()[F_DISRES].size(); fa += 3)
         {
-            int type;
-
-            type = (*il)[F_DISRES].iatoms[fa];
+            int type = il.list()[F_DISRES].iatoms[fa];
 
             np++;
-            npair = mtop.ffparams.iparams[type].disres.npair;
+            int npair = mtop.ffparams.iparams[type].disres.npair;
             if (np == npair)
             {
-                dd->nres += (ir->eDisre == DistanceRestraintRefinement::Ensemble ? 1 : nmol);
-                dd->npair += nmol * npair;
+                dd->nres += (ir->eDisre == DistanceRestraintRefinement::Ensemble ? 1 : il.nmol());
+                dd->npair += il.nmol() * npair;
                 np = 0;
 
                 type_min = std::min(type_min, type);
index 26de7b7725fa9b8e32e80604b37c5d70894eb4b3..6b41b649ea80e700c29bcc54159eeef2233e932f 100644 (file)
@@ -121,26 +121,24 @@ void init_orires(FILE*                 fplog,
     od->eig = nullptr;
     od->v   = nullptr;
 
-    int*                 nr_ex   = nullptr;
-    int                  typeMin = INT_MAX;
-    int                  typeMax = 0;
-    gmx_mtop_ilistloop_t iloop   = gmx_mtop_ilistloop_init(mtop);
-    int                  nmol;
-    while (const InteractionLists* il = gmx_mtop_ilistloop_next(iloop, &nmol))
-    {
-        const int numOrires = (*il)[F_ORIRES].size();
-        if (nmol > 1 && numOrires > 0)
+    int* nr_ex   = nullptr;
+    int  typeMin = INT_MAX;
+    int  typeMax = 0;
+    for (const auto il : IListRange(mtop))
+    {
+        const int numOrires = il.list()[F_ORIRES].size();
+        if (il.nmol() > 1 && numOrires > 0)
         {
             gmx_fatal(FARGS,
                       "Found %d copies of a molecule with orientation restrains while the current "
                       "code only supports a single copy. If you want to ensemble average, run "
                       "multiple copies of the system using the multi-sim feature of mdrun.",
-                      nmol);
+                      il.nmol());
         }
 
         for (int i = 0; i < numOrires; i += 3)
         {
-            int type = (*il)[F_ORIRES].iatoms[i];
+            int type = il.list()[F_ORIRES].iatoms[i];
             int ex   = mtop.ffparams.iparams[type].orires.ex;
             if (ex >= od->nex)
             {
index 0ccadf81e95e1161a55798c611bc28a085655d03..24d0d58fb564d929be4dc92785c976258af3e440 100644 (file)
@@ -156,13 +156,11 @@ SettleData::SettleData(const gmx_mtop_t& mtop) :
     useSimd_(getenv("GMX_DISABLE_SIMD_KERNELS") == nullptr)
 {
     /* Check that we have only one settle type */
-    int                  settle_type = -1;
-    gmx_mtop_ilistloop_t iloop       = gmx_mtop_ilistloop_init(mtop);
-    int                  nmol;
-    const int            nral1 = 1 + NRAL(F_SETTLE);
-    while (const InteractionLists* ilists = gmx_mtop_ilistloop_next(iloop, &nmol))
+    int       settle_type = -1;
+    const int nral1       = 1 + NRAL(F_SETTLE);
+    for (const auto ilists : IListRange(mtop))
     {
-        const InteractionList& ilist = (*ilists)[F_SETTLE];
+        const InteractionList& ilist = ilists.list()[F_SETTLE];
         for (int i = 0; i < ilist.size(); i += nral1)
         {
             if (settle_type == -1)
index 59e9e133569b5d8f2d8e84c5d986c3bce5125e7b..42eb320ddd3a4150c68cfbde2c6770b11b9fd28a 100644 (file)
@@ -238,70 +238,66 @@ gmx_bool gmx_mtop_atomloop_block_next(gmx_mtop_atomloop_block_t aloop, const t_a
     return TRUE;
 }
 
-typedef struct gmx_mtop_ilistloop
+IListIterator::IListIterator(const gmx_mtop_t& mtop, size_t molblock) :
+    mtop_(&mtop),
+    mblock_(molblock)
 {
-    const gmx_mtop_t* mtop;
-    int               mblock;
-} t_gmx_mtop_ilist;
+}
 
-gmx_mtop_ilistloop_t gmx_mtop_ilistloop_init(const gmx_mtop_t& mtop)
+IListIterator& IListIterator::operator++()
 {
-    struct gmx_mtop_ilistloop* iloop = nullptr;
-
-    snew(iloop, 1);
-
-    iloop->mtop   = &mtop;
-    iloop->mblock = -1;
-
-    return iloop;
+    mblock_++;
+    return *this;
 }
 
-static void gmx_mtop_ilistloop_destroy(gmx_mtop_ilistloop_t iloop)
+bool IListIterator::operator==(const IListIterator& o) const
 {
-    sfree(iloop);
+    return mtop_ == o.mtop_ && mblock_ == o.mblock_;
 }
 
-const InteractionLists* gmx_mtop_ilistloop_next(gmx_mtop_ilistloop_t iloop, int* nmol)
+const InteractionLists& IListProxy::list() const
 {
-    if (iloop == nullptr)
+    // one past the end means we want to take the
+    // intermolecular list instead.
+    if (it_->mblock_ == it_->mtop_->molblock.size())
     {
-        gmx_incons("gmx_mtop_ilistloop_next called without calling gmx_mtop_ilistloop_init");
+        return *it_->mtop_->intermolecular_ilist;
     }
-
-    iloop->mblock++;
-    if (iloop->mblock >= gmx::ssize(iloop->mtop->molblock))
+    else
     {
-        if (iloop->mblock == gmx::ssize(iloop->mtop->molblock) && iloop->mtop->bIntermolecularInteractions)
-        {
-            *nmol = 1;
-            return iloop->mtop->intermolecular_ilist.get();
-        }
-
-        gmx_mtop_ilistloop_destroy(iloop);
-        return nullptr;
+        return it_->mtop_->moltype[it_->mtop_->molblock[it_->mblock_].type].ilist;
     }
+}
 
-    *nmol = iloop->mtop->molblock[iloop->mblock].nmol;
-
-    return &iloop->mtop->moltype[iloop->mtop->molblock[iloop->mblock].type].ilist;
+int IListProxy::nmol() const
+{
+    // one past the end means we want to take the
+    // intermolecular list instead.
+    if (it_->mblock_ == it_->mtop_->molblock.size())
+    {
+        return 1;
+    }
+    else
+    {
+        return it_->mtop_->molblock[it_->mblock_].nmol;
+    }
 }
-typedef struct gmx_mtop_ilistloop_all
+
+IListRange::IListRange(const gmx_mtop_t& mtop) : begin_(mtop), end_(mtop, mtop.molblock.size())
 {
-    const gmx_mtop_t* mtop;
-    size_t            mblock;
-    int               mol;
-    int               a_offset;
-} t_gmx_mtop_ilist_all;
+    if (mtop.bIntermolecularInteractions)
+    {
+        end_ = IListIterator(mtop, mtop.molblock.size() + 1);
+    }
+}
 
 int gmx_mtop_ftype_count(const gmx_mtop_t& mtop, int ftype)
 {
-    int nmol = 0;
-    int n    = 0;
+    int n = 0;
 
-    gmx_mtop_ilistloop_t iloop = gmx_mtop_ilistloop_init(mtop);
-    while (const InteractionLists* il = gmx_mtop_ilistloop_next(iloop, &nmol))
+    for (const IListProxy il : IListRange(mtop))
     {
-        n += nmol * (*il)[ftype].size() / (1 + NRAL(ftype));
+        n += il.nmol() * il.list()[ftype].size() / (1 + NRAL(ftype));
     }
 
     if (mtop.bIntermolecularInteractions)
@@ -316,15 +312,13 @@ int gmx_mtop_interaction_count(const gmx_mtop_t& mtop, const int unsigned if_fla
 {
     int n = 0;
 
-    gmx_mtop_ilistloop_t iloop = gmx_mtop_ilistloop_init(mtop);
-    int                  nmol  = 0;
-    while (const InteractionLists* il = gmx_mtop_ilistloop_next(iloop, &nmol))
+    for (const IListProxy il : IListRange(mtop))
     {
         for (int ftype = 0; ftype < F_NRE; ftype++)
         {
             if ((interaction_function[ftype].flags & if_flags) == if_flags)
             {
-                n += nmol * (*il)[ftype].size() / (1 + NRAL(ftype));
+                n += il.nmol() * il.list()[ftype].size() / (1 + NRAL(ftype));
             }
         }
     }
index e4615c46bb09b3254f1c3b8912d2a0cf6e9a444a..c8cbc57a17e831a6573e0fa9376788955d4a1764 100644 (file)
@@ -157,6 +157,76 @@ private:
     AtomIterator begin_, end_;
 };
 
+class IListIterator;
+
+//! Proxy object returned from IListIterator
+class IListProxy
+{
+public:
+    //! Default constructor.
+    IListProxy(const IListIterator* it) : it_(it) {}
+    //! Access current global atom number.
+    const InteractionLists& list() const;
+    //! Access current molecule.
+    int nmol() const;
+
+private:
+    const IListIterator* it_;
+};
+
+/*! \brief
+ * Object that allows looping over all atoms in an mtop.
+ */
+class IListIterator :
+    public boost::stl_interfaces::proxy_iterator_interface<IListIterator, std::forward_iterator_tag, InteractionLists, IListProxy>
+{
+    using Base =
+            boost::stl_interfaces::proxy_iterator_interface<IListIterator, std::forward_iterator_tag, InteractionLists, IListProxy>;
+
+public:
+    //! Construct from topology.
+    explicit IListIterator(const gmx_mtop_t& mtop, size_t mblock = 0);
+
+    //! Prefix increment.
+    IListIterator& operator++();
+    using Base::   operator++;
+
+    //! Equality comparison.
+    bool operator==(const IListIterator& o) const;
+
+    //! Dereference operator. Returns proxy.
+    IListProxy operator*() const { return { this }; }
+
+private:
+    //! Global topology.
+    const gmx_mtop_t* mtop_;
+    //! Index of molecule block corresponding to the current location.
+    size_t mblock_;
+
+    friend class IListProxy;
+};
+
+
+/*! \brief
+ * Range over all interaction lists of topology.
+ *
+ * Includes the intermolecular interactions as the final element in the
+ * range if present.
+ */
+class IListRange
+{
+public:
+    //! Default constructor.
+    explicit IListRange(const gmx_mtop_t& mtop);
+    //! Iterator to begin of range.
+    IListIterator& begin() { return begin_; }
+    //! Iterator to end of range.
+    IListIterator& end() { return end_; }
+
+private:
+    IListIterator begin_, end_;
+};
+
 /* Abstract type for atom loop over atoms in all molecule blocks */
 typedef struct gmx_mtop_atomloop_block* gmx_mtop_atomloop_block_t;
 
@@ -180,20 +250,6 @@ gmx_mtop_atomloop_block_t gmx_mtop_atomloop_block_init(const gmx_mtop_t& mtop);
 gmx_bool gmx_mtop_atomloop_block_next(gmx_mtop_atomloop_block_t aloop, const t_atom** atom, int* nmol);
 
 
-/* Abstract type for ilist loop over all ilists */
-typedef struct gmx_mtop_ilistloop* gmx_mtop_ilistloop_t;
-
-/* Initialize an ilist loop over all molecule types in the system. */
-gmx_mtop_ilistloop_t gmx_mtop_ilistloop_init(const gmx_mtop_t& mtop);
-
-/* Loop to the next molecule,
- * When not at the end:
- *   returns a valid pointer to the next array ilist_mol[F_NRE],
- *   writes the number of molecules for this ilist in *nmol.
- * When at the end, destroys iloop and returns nullptr.
- */
-const InteractionLists* gmx_mtop_ilistloop_next(gmx_mtop_ilistloop_t iloop, int* nmol);
-
 /* Returns the total number of interactions in the system of type ftype */
 int gmx_mtop_ftype_count(const gmx_mtop_t& mtop, int ftype);