Extra options for computational electrophysiology.
authorCarsten Kutzner <ckutzne@gwdg.de>
Tue, 2 Dec 2014 10:49:02 +0000 (11:49 +0100)
committerGerrit Code Review <gerrit@gerrit.gromacs.org>
Wed, 7 Oct 2015 18:39:57 +0000 (20:39 +0200)
* Added two extra .mdp file parameters 'bulk-offset' that allow to specify
an offset of the swap layers from the compartment midplanes. This is useful
for setups where e.g. a transmembrane protein extends far into at least one
of the compartments. Without an offset, ions would be swapped in the vicinity
of the protein, which is not wanted. Adding an extended water layer comes
at the cost of performance, which is not the case for the offset solution.
* Also made the wording a bit clearer in some places
* Described the new parameters in the PDF manual, updated figure
* replaced usage of sprintf in output routine print_ionlist_legend() by snprintf
* Turned comments describing the variables entering the swapcoords.cpp
  functions into doxygen comments

Change-Id: I2a5314d112384b30f9c910135047cc2441192421

docs/manual/plots/compelsetup.pdf
docs/manual/special.tex
src/gromacs/fileio/tpxio.cpp
src/gromacs/gmxlib/txtdump.cpp
src/gromacs/gmxpreprocess/readir.cpp
src/gromacs/legacyheaders/types/inputrec.h
src/gromacs/swap/swapcoords.cpp
src/gromacs/timing/wallcycle.cpp

index b8101088282365a8ffd7063db57a23796b9271c7..4a333569175b006b37690b7407b7124c306838f6 100644 (file)
Binary files a/docs/manual/plots/compelsetup.pdf and b/docs/manual/plots/compelsetup.pdf differ
index 0d2823d9dbc9b3b70afb3a339913f6dba0117c35..26dcffc9e25f5ef21d06a1a039aee1bfdfd945cd 100644 (file)
@@ -1059,8 +1059,10 @@ important for studying channel rectification.
 
 \begin{figure}
 \centerline{\includegraphics[width=13.5cm]{plots/compelsetup.pdf}}
-\caption{Typical double-membrane setup for CompEL simulations (A, B). Plot (C) shows
-the potential difference $\Delta U$ resulting
+\caption{Typical double-membrane setup for CompEL simulations (A, B).
+Ion\,/\,water molecule exchanges will be performed as needed
+between the two light blue volumes around the dotted black lines (A).
+Plot (C) shows the potential difference $\Delta U$ resulting
 from the selected charge imbalance $\Delta q_{ref}$ between the compartments.}
 \label{fig:compelsetup}
 \end{figure}
@@ -1096,11 +1098,13 @@ Ions will be exchanged between compartments depending on their $z$-positions alo
 {\tt swap-frequency} determines how often a swap attempt will be made.
 This step requires that the positions of the ions, solvent, and swap groups are
 communicated between the parallel processes, so if chosen too small it can decrease the simulation
-performance.
+performance. The {\tt Position swapping} entry in the cycle and time accounting
+table at the end of the {\tt md.log} file summarizes the amount of runtime spent
+in the swap module.
 {\small
 \begin{verbatim}
-split-group0   = channel0     ; Defines compartment boundary 
-split-group1   = channel1     ; Defines other compartment boundary 
+split-group0   = channel0     ; Defines compartment boundary
+split-group1   = channel1     ; Defines other compartment boundary
 massw-split0   = no           ; use mass-weighted center?
 massw-split1   = no
 \end{verbatim}}
@@ -1112,6 +1116,18 @@ geometrical centers will be used ($\times$ in \figref{compelsetup} A). If, such
 channel is selected as split group, the center of the channel will define the dividing
 plane between the compartments (dashed horizontal line in the figure). All index groups
 must be defined in the index file.
+
+If, to restore the requested ion counts, an ion from one compartment has to be exchanged
+with a water molecule from the other compartment, then those molecules are swapped
+which have the largest distance to the compartment-defining boundaries
+(dashed horizontal lines in \figref{compelsetup} A). Depending on the ion concentration,
+this effectively results in exchanges of molecules between the light blue volumes.
+If a channel is very asymmetric in $z$-direction and would extend into one of the
+swap volumes, one can offset the swap exchange plane with the {\tt bulk-offset}
+parameter. A value of 0.0 means no offset $b$, values $-1.0 < b < 0$ move the
+swap exchange plane closer to the lower, values $0 < b < 1.0$ closer to the upper
+membrane. The figure \figref{compelsetup} A (left) depicts that for the {\bf A} compartment.
 {\small
 \begin{verbatim}
 swap-group     = NA+_CL-      ; Ions to be included in exchange
index 5e8d2929a4e013e57ba02444131bdeae1cdf3ed9..927f3a0a3a703dc499c7801cc058cdbe7efbf5c7 100644 (file)
@@ -96,6 +96,7 @@ enum tpxv {
     tpxv_PullCoordTypeGeom,                                  /**< add pull type and geometry per group and flat-bottom */
     tpxv_PullGeomDirRel,                                     /**< add pull geometry direction-relative */
     tpxv_IntermolecularBondeds,                              /**< permit inter-molecular bonded interactions in the topology */
+    tpxv_CompElWithSwapLayerOffset,                          /**< added parameters for improved CompEl setups */
     tpxv_Count                                               /**< the total number of tpxv versions */
 };
 
@@ -739,7 +740,7 @@ static void do_rot(t_fileio *fio, t_rot *rot, gmx_bool bRead)
 }
 
 
-static void do_swapcoords(t_fileio *fio, t_swapcoords *swap, gmx_bool bRead)
+static void do_swapcoords(t_fileio *fio, t_swapcoords *swap, gmx_bool bRead, int file_version)
 {
     int j;
 
@@ -783,6 +784,14 @@ static void do_swapcoords(t_fileio *fio, t_swapcoords *swap, gmx_bool bRead)
         gmx_fio_do_int(fio, swap->ncations[j]);
     }
 
+    if (file_version >= tpxv_CompElWithSwapLayerOffset)
+    {
+        for (j = 0; j < eCompNR; j++)
+        {
+            gmx_fio_do_real(fio, swap->bulkOffset[j]);
+        }
+    }
+
 }
 
 
@@ -1746,7 +1755,7 @@ static void do_inputrec(t_fileio *fio, t_inputrec *ir, gmx_bool bRead,
             {
                 snew(ir->swap, 1);
             }
-            do_swapcoords(fio, ir->swap, bRead);
+            do_swapcoords(fio, ir->swap, bRead, file_version);
         }
     }
 
index 432fa5a0cbac760328eae52b588d62a30e563d77..8fae65ec19718c8547b3b85dad77634a74d43019 100644 (file)
@@ -850,6 +850,11 @@ static void pr_swap(FILE *fp, int indent, t_swapcoords *swap)
         sprintf(str, "cations%c", j+'A');
         PI(str, swap->ncations[j]);
     }
+    for (j = 0; j < 2; j++)
+    {
+        sprintf(str, "bulk-offset%c", j+'A');
+        PR(str, swap->bulkOffset[j]);
+    }
     PR("threshold", swap->threshold);
 }
 
index b34de80ead4d833b399f7b34e97132da028cfc97..4745447dac35cef6e86815f8748fdc922cc3fc13 100644 (file)
@@ -2261,6 +2261,7 @@ void get_ir(const char *mdparin, const char *mdparout,
     STYPE ("E-z",     is->efield_z,   NULL);
     STYPE ("E-zt",    is->efield_zt,  NULL);
 
+    /* Ion/water position swapping ("computational electrophysiology") */
     CCTYPE("Ion/water position swapping for computational electrophysiology setups");
     CTYPE("Swap positions along direction: no, X, Y, Z");
     EETYPE("swapcoords", ir->eSwapCoords, eSwapTypes_names);
@@ -2299,6 +2300,19 @@ void get_ir(const char *mdparin, const char *mdparout,
         ITYPE("cationsA", ir->swap->ncations[0], -1);
         ITYPE("anionsB", ir->swap->nanions[1], -1);
         ITYPE("cationsB", ir->swap->ncations[1], -1);
+
+        CTYPE("By default (i.e. bulk offset = 0.0), ion/water exchanges happen between layers");
+        CTYPE("at maximum distance (= bulk concentration) to the split group layers. However,");
+        CTYPE("an offset b (-1.0 < b < +1.0) can be specified to offset the bulk layer from the middle at 0.0");
+        CTYPE("towards one of the compartment-partitioning layers (at +/- 1.0).");
+        RTYPE("bulk-offsetA", ir->swap->bulkOffset[0], 0.0);
+        RTYPE("bulk-offsetB", ir->swap->bulkOffset[1], 0.0);
+        if (!(ir->swap->bulkOffset[0] > -1.0 && ir->swap->bulkOffset[0] < 1.0)
+            || !(ir->swap->bulkOffset[1] > -1.0 && ir->swap->bulkOffset[1] < 1.0) )
+        {
+            warning_error(wi, "Bulk layer offsets must be > -1.0 and < 1.0 !");
+        }
+
         CTYPE("Start to swap ions if threshold difference to requested count is reached");
         RTYPE("threshold", ir->swap->threshold, 1.0);
     }
index 69430a2eda26f13fed93b6511d7e9b862309eada..9c6bfcb216b4bca4ed9b16bb0af0861e19ad4386 100644 (file)
@@ -257,29 +257,31 @@ typedef struct t_IMD {
     struct t_gmx_IMD *setup; /* Stores non-inputrec IMD data                  */
 } t_IMD;
 
-/* Abstract types for position swapping only defined in swapcoords.c */
+/* Abstract types for position swapping only defined in swapcoords.cpp */
 typedef struct t_swap *gmx_swapcoords_t;
 
 typedef struct t_swapcoords {
-    int              nstswap;           /* Every how many steps a swap is attempted?    */
-    int              nat;               /* Number of atoms in the ion group             */
-    int              nat_split[2];      /* Number of atoms in the split group           */
-    int              nat_sol;           /* Number of atoms in the solvent group         */
-    atom_id         *ind;               /* The global ion group atoms numbers           */
-    atom_id         *ind_split[2];      /* Split groups for compartment partitioning    */
-    atom_id         *ind_sol;           /* The global solvent group atom numbers        */
-    gmx_bool         massw_split[2];    /* Use mass-weighted positions in split group?  */
-    real             cyl0r, cyl1r;      /* Split cylinders defined by radius, upper and */
-    real             cyl0u, cyl1u;      /* ... lower extension. The split cylinders de- */
-    real             cyl0l, cyl1l;      /* ... fine the channels and are each anchored  */
-                                        /* ... in the center of the split group         */
-    int              nanions[eCompNR];  /* Requested number of anions and               */
-    int              nAverage;          /* Coupling constant (nr of swap attempt steps) */
-    real             threshold;         /* Ion counts may deviate from the requested
-                                           values by +-threshold before a swap is done  */
-    int              ncations[eCompNR]; /* ... cations for both compartments            */
-    gmx_swapcoords_t si_priv;           /* swap private data accessible in
-                                         * swapcoords.c                                 */
+    int              nstswap;             /* Every how many steps a swap is attempted?    */
+    int              nat;                 /* Number of atoms in the ion group             */
+    int              nat_split[2];        /* Number of atoms in the split group           */
+    int              nat_sol;             /* Number of atoms in the solvent group         */
+    atom_id         *ind;                 /* The global ion group atoms numbers           */
+    atom_id         *ind_split[2];        /* Split groups for compartment partitioning    */
+    atom_id         *ind_sol;             /* The global solvent group atom numbers        */
+    gmx_bool         massw_split[2];      /* Use mass-weighted positions in split group?  */
+    real             cyl0r, cyl1r;        /* Split cylinders defined by radius, upper and */
+    real             cyl0u, cyl1u;        /* ... lower extension. The split cylinders de- */
+    real             cyl0l, cyl1l;        /* ... fine the channels and are each anchored  */
+                                          /* ... in the center of the split group         */
+    int              nanions[eCompNR];    /* Requested number of anions and               */
+    int              nAverage;            /* Coupling constant (nr of swap attempt steps) */
+    real             threshold;           /* Ion counts may deviate from the requested
+                                             values by +-threshold before a swap is done  */
+    int              ncations[eCompNR];   /* ... cations for both compartments            */
+    real             bulkOffset[eCompNR]; /* Offset of the swap layer (='bulk') w.r.t.
+                                             the compartment-defining layers              */
+    gmx_swapcoords_t si_priv;             /* swap private data accessible in
+                                           * swapcoords.cpp                               */
 } t_swapcoords;
 
 
index 76b01ea411c7bb223852439ed02ec4626e0e75a3..2de9dbd5c4aec559af4f9c13727a98e9f3fd58f3 100644 (file)
@@ -66,6 +66,7 @@
 #include "gromacs/utility/cstringutil.h"
 #include "gromacs/utility/fatalerror.h"
 #include "gromacs/utility/smalloc.h"
+#include "gromacs/utility/snprintf.h"
 
 static const char *SwS      = {"SWAP:"};                                           /**< For output that comes from the swap module */
 static const char *SwSEmpty = {"     "};                                           /**< Placeholder for multi-line output */
@@ -113,7 +114,8 @@ typedef struct swap_compartment
                                                    the compartment conditions.                   */
     int               *nat_past;              /**< Past ion counts for time-averaging.           */
     int               *ind;                   /**< Indices to coll array of atoms.               */
-    real              *dist;                  /**< Distance of atom to compartment center.       */
+    real              *dist;                  /**< Distance of atom to bulk layer, which is
+                                                   normally the center layer of the compartment  */
     int                nalloc;                /**< Allocation size for ind array.                */
     int                inflow_netto;          /**< Net inflow of ions into this compartment.     */
 } t_compartment;
@@ -186,15 +188,25 @@ typedef struct t_swap
  *               v  d_down
  *
  * \endcode
+ *
+ * \param[in] point    The position (xyz) under consideration.
+ * \param[in] center   The center of the cylinder.
+ * \param[in] d_up     The upper extension of the cylinder.
+ * \param[in] d_down   The lower extension.
+ * \param[in] r_cyl2   Cylinder radius squared.
+ * \param[in] pbc      Structure with info about periodic boundary conditions.
+ * \param[in] normal   The membrane normal direction is typically 3, i.e. z, but can be x or y also.
+ *
+ * \returns   Whether the point is inside the defined cylindric channel.
  */
 static gmx_bool is_in_channel(
-        rvec   point,  /* Point under consideration */
-        rvec   center, /* 'Center' of cylinder */
-        real   d_up,   /* Upper extension */
-        real   d_down, /* Lower extensions */
-        real   r_cyl2, /* Cylinder radius squared */
+        rvec   point,
+        rvec   center,
+        real   d_up,
+        real   d_down,
+        real   r_cyl2,
         t_pbc *pbc,
-        int    normal) /* The membrane normal direction is typically 3, i.e. ZZ, but can be X or Y also */
+        int    normal)
 {
     rvec dr;
     int  plane1, plane2; /* Directions tangential to membrane */
@@ -316,33 +328,56 @@ static void get_molecule_center(
 
 
 
-/*! \brief Return TRUE if ion is found in the compartment.
+/*! \brief Return TRUE if position x of ion (or water) is found in the compartment,
+ * i.e. between w1 and w2.
  *
- * Returns TRUE if x is between (w1+gap) and (w2-gap)
+ * One can define and additional offset "b" if one wants to exchange ions/water
+ * to or from a plane not directly in the middle of w1 and w2. The offset can be
+ * in  ]-1.0, ..., +1.0 [.
+ * A bulkOffset of 0.0 means 'no offset', so the swap-layer is directly in the
+ * middle between w1 and w2. Offsets -1.0 < b <  0.0 will yield swaps nearer to w1,
+ * whereas offsets  0.0 < 0 < +1.0 will yield swaps nearer to w2.
  *
  * \code
  *
- * ||-----------|--+--|----------o----------|--+--|---------------------||
- *                w1   ?????????????????????  w2
+ * ||--------------+-------------|-------------+------------------------||
+ *                w1  ? ? ? ? ? ? ? ? ? ? ?   w2
+ * ||--------------+-------------|----b--------+------------------------||
+ *                -1            0.0           +1
  *
  * \endcode
+ *
+ * \param[in]  w1               Position of 'wall' atom 1.
+ * \param[in]  w2               Position of 'wall' atom 2.
+ * \param[in]  x                Position of the ion or the water molecule under consideration.
+ * \param[in]  l                Length of the box, from || to || in the sketch.
+ * \param[in]  bulkOffset       Where is the bulk layer "b" to be found between w1 and w2?
+ * \param[out] distance_from_b  Distance of x to the bulk layer "b".
+ *
+ * \returns TRUE if x is between w1 and w2.
+ *
+ * Also computes the distance of x to the compartment center (the layer that is
+ * normally situated in the middle of w1 and w2 that would be considered as having
+ * the bulk concentration of ions).
  */
 static gmx_bool compartment_contains_atom(
-        real  w1, /* position of wall atom 1 */
-        real  w2, /* position of wall atom 2 */
-        real  gap,
+        real  w1,
+        real  w2,
         real  x,
-        real  l,  /* length of the box, from || to || in the sketch */
-        real *distance_from_center)
+        real  l,
+        real  bulkOffset,
+        real *distance_from_b)
 {
     real m, l_2;
+    real width;
 
 
     /* First set the origin in the middle of w1 and w2 */
-    m   = 0.5 * (w1 + w2);
-    w1 -= m;
-    w2 -= m;
-    x  -= m;
+    m     = 0.5 * (w1 + w2);
+    w1   -= m;
+    w2   -= m;
+    x    -= m;
+    width = w2 - w1;
 
     /* Now choose the PBC image of x that is closest to the origin: */
     l_2 = 0.5*l;
@@ -355,10 +390,10 @@ static gmx_bool compartment_contains_atom(
         x += l;
     }
 
-    *distance_from_center = (real)fabs(x);
+    *distance_from_b = (real)fabs(x - bulkOffset*0.5*width);
 
     /* Return TRUE if we now are in area "????" */
-    if ( (x >= (w1+gap)) &&  (x < (w2-gap)) )
+    if ( (x >= w1) &&  (x < w2) )
     {
         return TRUE;
     }
@@ -393,11 +428,17 @@ static void update_time_window(t_compartment *comp, int values, int replace)
 }
 
 
-/*! \brief Add atom with collective index ci to the list 'comp'. */
+/*! \brief Add the atom with collective index ci to the atom list in compartment 'comp'.
+ *
+ * \param[in]     ci        Index of this ion in the collective xc array.
+ * \param[inout]  comp      Compartment to add this atom to.
+ * \param[in]     distance  Shortest distance of this atom to the bulk layer,
+ *                          from which ion/water pairs are selected for swapping.
+ */
 static void add_to_list(
-        int            ci,       /* index of this ion in the collective array xc, qc */
-        t_compartment *comp,     /* Compartment to add this atom to */
-        real           distance) /* Shortest distance of this atom to the compartment center */
+        int            ci,
+        t_compartment *comp,
+        real           distance)
 {
     int nr;
 
@@ -429,7 +470,7 @@ static void get_compartment_boundaries(
 
     if (c >= eCompNR)
     {
-        gmx_fatal(FARGS, "No compartment %d.", c);
+        gmx_fatal(FARGS, "No compartment %c.", c+'A');
     }
 
     pos0 = s->group[eGrpSplit0].center[s->swapdim];
@@ -662,7 +703,7 @@ static void compartmentalize_ions(
             type = iong->qc[i] < 0 ? eIonNEG : eIonPOS;
 
             /* Is this ion in the compartment that we look at? */
-            if (compartment_contains_atom(left, right, 0, iong->xc[i][sd], box[sd][sd], &dist) )
+            if (compartment_contains_atom(left, right, iong->xc[i][sd], box[sd][sd], sc->bulkOffset[comp], &dist) )
             {
                 /* Now put it into the list containing only ions of its type */
                 add_to_list(i, &s->comp[comp][type], dist);
@@ -773,7 +814,7 @@ static void compartmentalize_solvent(
         /* Loop over the solvent MOLECULES */
         for (i = 0; i < sc->nat_sol; i += apm)
         {
-            if (compartment_contains_atom(left, right, 0, solg->xc[i][sd], box[sd][sd], &dist))
+            if (compartment_contains_atom(left, right, solg->xc[i][sd], box[sd][sd], sc->bulkOffset[comp], &dist))
             {
                 /* Add the whole molecule to the list */
                 for (j = 0; j < apm; j++)
@@ -1084,7 +1125,7 @@ static void print_ionlist_legend(t_inputrec             *ir,
 {
     const char **legend;
     int          ic, count, ii;
-    char         buf[256];
+    char         buf[STRLEN];
     t_swap      *s;
 
 
@@ -1095,30 +1136,30 @@ static void print_ionlist_legend(t_inputrec             *ir,
     {
         for (ii = 0; ii < eIonNR; ii++)
         {
-            sprintf(buf, "%s %ss", CompStr[ic], IonString[ii]);
+            snprintf(buf, STRLEN, "%s %ss", CompStr[ic], IonString[ii]);
             legend[count++] = gmx_strdup(buf);
-            sprintf(buf, "%s av. mismatch to %d%s",
-                    CompStr[ic], s->comp[ic][ii].nat_req, IonStr[ii]);
+            snprintf(buf, STRLEN, "%s av. mismatch to %d%s",
+                     CompStr[ic], s->comp[ic][ii].nat_req, IonStr[ii]);
             legend[count++] = gmx_strdup(buf);
-            sprintf(buf, "%s netto %s influx", CompStr[ic], IonString[ii]);
+            snprintf(buf, STRLEN, "%s netto %s influx", CompStr[ic], IonString[ii]);
             legend[count++] = gmx_strdup(buf);
         }
     }
-    sprintf(buf, "%scenter of %s of split group 0", SwapStr[ir->eSwapCoords], (NULL != s->group[eGrpSplit0].m) ? "mass" : "geometry");
+    snprintf(buf, STRLEN, "%scenter of %s of split group 0", SwapStr[ir->eSwapCoords], (NULL != s->group[eGrpSplit0].m) ? "mass" : "geometry");
     legend[count++] = gmx_strdup(buf);
-    sprintf(buf, "%scenter of %s of split group 1", SwapStr[ir->eSwapCoords], (NULL != s->group[eGrpSplit1].m) ? "mass" : "geometry");
+    snprintf(buf, STRLEN, "%scenter of %s of split group 1", SwapStr[ir->eSwapCoords], (NULL != s->group[eGrpSplit1].m) ? "mass" : "geometry");
     legend[count++] = gmx_strdup(buf);
 
     for (ic = 0; ic < eChanNR; ic++)
     {
         for (ii = 0; ii < eIonNR; ii++)
         {
-            sprintf(buf, "A->ch%d->B %s permeations", ic, IonString[ii]);
+            snprintf(buf, STRLEN, "A->ch%d->B %s permeations", ic, IonString[ii]);
             legend[count++] = gmx_strdup(buf);
         }
     }
 
-    sprintf(buf, "leakage");
+    snprintf(buf, STRLEN, "leakage");
     legend[count++] = gmx_strdup(buf);
 
     xvgr_legend(s->fpout, count, legend, oenv);
@@ -1566,15 +1607,22 @@ void init_swapcoords(FILE                   *fplog,
 
         if (!bAppend)
         {
+            if ( (0 != sc->bulkOffset[eCompA]) || (0 != sc->bulkOffset[eCompB]) )
+            {
+                fprintf(s->fpout, "#\n");
+                fprintf(s->fpout, "# You provided an offset for the position of the bulk layer(s).\n");
+                fprintf(s->fpout, "# That means the layers to/from which ions and water molecules are swapped\n");
+                fprintf(s->fpout, "# are not midway (= at 0.0) between the compartment-defining layers (at +/- 1.0).\n");
+                fprintf(s->fpout, "# bulk-offsetA = %g\n", sc->bulkOffset[eCompA]);
+                fprintf(s->fpout, "# bulk-offsetB = %g\n", sc->bulkOffset[eCompB]);
+            }
+
             fprintf(s->fpout, "#\n");
             fprintf(s->fpout, "# split0 cylinder radius %f nm, up %f nm, down %f nm\n",
                     sc->cyl0r, sc->cyl0u, sc->cyl0l);
             fprintf(s->fpout, "# split1 cylinder radius %f nm, up %f nm, down %f nm\n",
                     sc->cyl1r, sc->cyl1u, sc->cyl1l);
-        }
 
-        if (!bAppend)
-        {
             fprintf(s->fpout, "#\n");
             if (!bRerun)
             {
@@ -1672,11 +1720,11 @@ void init_swapcoords(FILE                   *fplog,
 
         if (bVerbose)
         {
-            fprintf(stderr, "%s Requested charge imbalance is Q(A) - Q(B) = %gz.\n", SwS, s->deltaQ);
+            fprintf(stderr, "%s Requested charge imbalance is Q(A) - Q(B) = %g e.\n", SwS, s->deltaQ);
         }
         if (!bAppend)
         {
-            fprintf(s->fpout, "# Requested charge imbalance is Q(A)-Q(B) = %gz.\n", s->deltaQ);
+            fprintf(s->fpout, "# Requested charge imbalance is Q(A)-Q(B) = %g e.\n", s->deltaQ);
         }
     }
 
@@ -1747,14 +1795,20 @@ static gmx_bool need_swap(t_swapcoords *sc)
 }
 
 
-/*! \brief Return index of atom that we can use for swapping.
+/*! \brief Return the index of an atom or molecule suitable for swapping.
+ *
+ * Returns the index of an atom that is far off the compartment boundaries,
+ * that is near to the bulk layer to/from which the swaps take place.
+ * Other atoms of the molecule (if any) will directly follow the returned index.
+ *
+ * \param[in] comp  Structure containing compartment-specific data.
+ * \param[in] apm   Atoms per molecule - just return the first atom index of a molecule
  *
- * Returns the index of an atom that is far off the compartment boundaries.
- * Other atoms of the molecule (if any) will directly follow the returned index
+ * \returns Index of the first atom of the molecule chosen for a position exchange.
  */
 static int get_index_of_distant_atom(
         t_compartment *comp,
-        int            apm) /* Atoms per molecule - just return the first atom index of a molecule */
+        int            apm)
 {
     int  i, ibest = -1;
     real d = GMX_REAL_MAX;
index 2c20d56ed5169eee25d94f4d8f0248b0d024de3f..ba90d71bd08bcba3dd3296847845453adc8490f0 100644 (file)
@@ -109,7 +109,7 @@ static const char *wcn[ewcNR] =
     "PME wait for PP", "Wait + Recv. PME F", "Wait GPU nonlocal", "Wait GPU local", "Wait GPU loc. est.", "NB X/F buffer ops.",
     "Vsite spread", "COM pull force",
     "Write traj.", "Update", "Constraints", "Comm. energies",
-    "Enforced rotation", "Add rot. forces", "Coordinate swapping", "IMD", "Test"
+    "Enforced rotation", "Add rot. forces", "Position swapping", "IMD", "Test"
 };
 
 #ifdef GMX_CYCLE_SUBCOUNTERS