Merge "Merge release-4-6 into master"
authorMark Abraham <mark.j.abraham@gmail.com>
Wed, 5 Mar 2014 06:23:00 +0000 (07:23 +0100)
committerGerrit Code Review <gerrit@gerrit.gromacs.org>
Wed, 5 Mar 2014 06:23:00 +0000 (07:23 +0100)
CMakeLists.txt
cmake/gmxTestZLib.cmake [new file with mode: 0644]
manual/algorithms.tex
src/gromacs/fileio/tpxio.c
src/gromacs/gmxpreprocess/calc_verletbuf.c
src/gromacs/gmxpreprocess/readir.c
src/gromacs/tools/compare.c

index a450d1a7be9159948916514d8346333bee4fb2f1..eb41e7a4d6a778c5c0566b6809907acb5bf9a03f 100644 (file)
@@ -804,6 +804,9 @@ endif()
 
 if(GMX_USE_TNG)
     find_package(ZLIB)
+    include(gmxTestZLib)
+    gmx_test_zlib(HAVE_ZLIB)
+    set(TNG_BUILD_WITH_ZLIB ${HAVE_ZLIB} CACHE BOOL  "Build TNG with zlib compression")
     set(TNG_BUILD_FORTRAN OFF CACHE BOOL "Build Fortran compatible TNG library and examples for testing")
     set(TNG_BUILD_EXAMPLES OFF CACHE BOOL "Build examples showing usage of the TNG API")
     set(TNG_BUILD_COMPRESSION_TESTS OFF CACHE BOOL "Build tests of the TNG compression library")
diff --git a/cmake/gmxTestZLib.cmake b/cmake/gmxTestZLib.cmake
new file mode 100644 (file)
index 0000000..21d2417
--- /dev/null
@@ -0,0 +1,60 @@
+#
+# This file is part of the GROMACS molecular simulation package.
+#
+# Copyright (c) 2014, 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.
+#
+# GROMACS is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public License
+# as published by the Free Software Foundation; either version 2.1
+# of the License, or (at your option) any later version.
+#
+# GROMACS is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with GROMACS; if not, see
+# http://www.gnu.org/licenses, or write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+#
+# If you want to redistribute modifications to GROMACS, please
+# consider that scientific software is very special. Version
+# control is crucial - bugs must be traceable. We will be happy to
+# consider code for inclusion in the official distribution, but
+# derived work must not be called official GROMACS. Details are found
+# in the README & COPYING files - if they are missing, get the
+# official version at http://www.gromacs.org.
+#
+# To help us fund GROMACS development, we humbly ask that you cite
+# the research papers on the package. Check out http://www.gromacs.org.
+
+# - Define macro to check if linking to zlib actually works,
+# because the find_package macro is content if one exists.  This can
+# fail in cross-compilation environments, and we want to know about
+# zlib so the zlib TNG support is built only when it will work.
+#
+#  GMX_TEST_ZLIB(VARIABLE)
+#
+#  VARIABLE will be set to true if zlib support is present
+
+include(CheckLibraryExists)
+include(gmxOptionUtilities)
+function(GMX_TEST_ZLIB VARIABLE)
+    if(ZLIB_FOUND)
+        gmx_check_if_changed(_do_zlib_recompile ZLIB_INCLUDE_DIR ZLIB_LIBRARIES)
+        if(_do_zlib_recompile)
+            unset(ZLIB_LINKS_OK CACHE)
+        endif()
+        check_library_exists("${ZLIB_LIBRARIES}" "zlibVersion" "" ZLIB_LINKS_OK)
+        set(${VARIABLE} ${ZLIB_LINKS_OK} PARENT_SCOPE)
+    else()
+        set(${VARIABLE} OFF PARENT_SCOPE)
+    endif()
+endfunction()
+
+
+
index 61a5a755994a128943878a80689d18e65b2a10c6..f0938f884c133021a537aa9a2e82b88d3a37c7c0 100644 (file)
@@ -646,14 +646,23 @@ the inter particle distance changes from $r_0$ to $r_t$, as:
 \nonumber\\
 & &
 \phantom{4 \pi (r_\ell+\sigma)^2 \rho_2 \int_{-\infty}^{r_c} \int_{r_\ell}^\infty \Big[}
-V''(r_c)\frac{1}{2}(r_t - r_c)^2 \Big] G\!\left(\frac{r_t-r_0}{\sigma}\right) d r_0 \, d r_t\\
+V''(r_c)\frac{1}{2}(r_t - r_c)^2 +
+\nonumber\\
+& &
+\phantom{4 \pi (r_\ell+\sigma)^2 \rho_2 \int_{-\infty}^{r_c} \int_{r_\ell}^\infty \Big[}
+V'''(r_c)\frac{1}{6}(r_t - r_c)^3 \Big] G\!\left(\frac{r_t-r_0}{\sigma}\right)
+d r_0 \, d r_t\\
 &=&
 4 \pi (r_\ell+\sigma)^2 \rho_2 \bigg\{
 \frac{1}{2}V'(r_c)\left[r_b \sigma G\!\left(\frac{r_b}{\sigma}\right) - (r_b^2+\sigma^2)E\!\left(\frac{r_b}{\sigma}\right) \right] +
 \nonumber\\
 & &
 \phantom{4 \pi (r_\ell+\sigma)^2 \rho_2 \bigg\{ }
-\frac{1}{6}V''(r_c)\left[ \sigma(r_b^2+\sigma^2)G\!\left(\frac{r_b}{\sigma}\right) - r_b(r_b^2+3\sigma^2 ) E\!\left(\frac{r_b}{\sigma}\right) \right]
+\frac{1}{6}V''(r_c)\left[ \sigma(r_b^2+2\sigma^2)G\!\left(\frac{r_b}{\sigma}\right) - r_b(r_b^2+3\sigma^2 ) E\!\left(\frac{r_b}{\sigma}\right) \right] +
+\nonumber\\
+& &
+\phantom{4 \pi (r_\ell+\sigma)^2 \rho_2 \bigg\{ }
+\frac{1}{24}V'''(r_c)\left[ r_b\sigma(r_b^2+5\sigma^2)G\!\left(\frac{r_b}{\sigma}\right) - (r_b^4+6r_b^2\sigma^2+3\sigma^4 ) E\!\left(\frac{r_b}{\sigma}\right) \right]
 \bigg\}
 \end{eqnarray}
 
index 95ce61b7a24bfb46183ed86efe01493d84c0a425..000f0916b4fc30942d8d44fb536e211a794a2d91 100644 (file)
 
 #define TPX_TAG_RELEASE  "release"
 
-/* This is the tag string which is stored in the tpx file.
- * Change this if you want to change the tpx format in a feature branch.
- * This ensures that there will not be different tpx formats around which
- * can not be distinguished.
+/*! \brief Tag string for the file format written to run input files
+ * written by this version of the code.
+ *
+ * Change this if you want to change the run input format in a feature
+ * branch. This ensures that there will not be different run input
+ * formats around which cannot be distinguished, while not causing
+ * problems rebasing the feature branch onto upstream changes. When
+ * merging with mainstream GROMACS, set this tag string back to
+ * TPX_TAG_RELEASE, and instead add an element to tpxv and set
+ * tpx_version to that.
  */
 static const char *tpx_tag = TPX_TAG_RELEASE;
 
-
-/* The tpx_version number should be increased whenever the file format changes!
+/*! \brief Enum of values that describe the contents of a tpr file
+ * whose format matches a version number
  *
- * The following comment section helps to keep track of which feature has been
- * added in which version.
+ * The enum helps the code be more self-documenting and ensure merges
+ * do not silently resolve when two patches make the same bump. When
+ * adding new functionality, add a new element to the end of this
+ * enumeration, change the definition of tpx_version, and write code
+ * below that does the right thing according to the value of
+ * file_version. */
+enum tpxv {
+    tpxv_ComputationalElectrophysiology = 96, /**< support for ion/water position swaps (computational electrophysiology) */
+    tpxv_Use64BitRandomSeed                   /**< change ld_seed from int to gmx_int64_t */
+};
+
+/*! \brief Version number of the file format written to run input
+ * files by this version of the code.
  *
- * version  feature added
- *    96    support for ion/water position swaps (computational electrophysiology)
- *    97    switch ld_seed from int to gmx_int64_t
+ * The tpx_version number should be increased whenever the file format
+ * in the main development branch changes, generally to the highest
+ * value present in tpxv. Backward compatibility for reading old run
+ * input files is maintained by checking this version number against
+ * that of the file and then using the correct code path.
  *
- * The following macros help the code be more self-documenting and
- * ensure merges do not silently resolve when two patches make the
- * same bump to the number. Unfortunately, compilers don't like
- * initializing a const int with a const int, so we have to be a bit
- * dirty and use a macro.
- */
-#define tpx_version_use_64_bit_random_seed 97
-static const int tpx_version = tpx_version_use_64_bit_random_seed;
+ * When developing a feature branch that needs to change the run input
+ * file format, change tpx_tag instead. */
+static const int tpx_version = tpxv_Use64BitRandomSeed;
 
 
 /* This number should only be increased when you edit the TOPOLOGY section
@@ -1416,7 +1430,7 @@ static void do_inputrec(t_fileio *fio, t_inputrec *ir, gmx_bool bRead,
         gmx_fio_do_real(fio, bd_temp);
     }
     gmx_fio_do_real(fio, ir->bd_fric);
-    if (file_version >= tpx_version_use_64_bit_random_seed)
+    if (file_version >= tpxv_Use64BitRandomSeed)
     {
         gmx_fio_do_int64(fio, ir->ld_seed);
     }
@@ -1696,7 +1710,7 @@ static void do_inputrec(t_fileio *fio, t_inputrec *ir, gmx_bool bRead,
     }
 
     /* Swap ions */
-    if (file_version >= 96)
+    if (file_version >= tpxv_ComputationalElectrophysiology)
     {
         gmx_fio_do_int(fio, ir->eSwapCoords);
         if (ir->eSwapCoords != eswapNO)
index ea383bf633d4494baad8286428a5f69f71536f9f..5862d61b9ea59f2fa3410b04a603dae14ff8b0d3 100644 (file)
@@ -546,18 +546,18 @@ static void approx_2dof(real s2, real x, real *shift, real *scale)
 static real ener_drift(const verletbuf_atomtype_t *att, int natt,
                        const gmx_ffparams_t *ffp,
                        real kT_fac,
-                       real md_ljd, real dd_ljd,
-                       real md_ljr, real dd_ljr,
-                       real md_el, real dd_el,
+                       real md1_ljd, real d2_ljd, real md3_ljd,
+                       real md1_ljr, real d2_ljr, real md3_ljr,
+                       real md1_el,  real d2_el,
                        real r_buffer,
                        real rlist, real boxvol)
 {
-    double drift_tot, pot1, pot2, pot;
+    double drift_tot, pot1, pot2, pot3, pot;
     int    i, j;
     real   s2i_2d, s2i_3d, s2j_2d, s2j_3d, s2, s;
     int    ti, tj;
-    real   md, dd;
-    real   sc_fac, rsh;
+    real   md1, d2, md3;
+    real   sc_fac, rsh, rsh2;
     double c_exp, c_erfc;
 
     drift_tot = 0;
@@ -580,16 +580,21 @@ static real ener_drift(const verletbuf_atomtype_t *att, int natt,
              * pairs will partially cancel.
              */
             /* -dV/dr at the cut-off for LJ + Coulomb */
-            md =
-                md_ljd*ffp->iparams[ti*ffp->atnr+tj].lj.c6 +
-                md_ljr*ffp->iparams[ti*ffp->atnr+tj].lj.c12 +
-                md_el*att[i].prop.q*att[j].prop.q;
-
-            /* d2V/dr2 at the cut-off for Coulomb, we neglect LJ */
-            dd =
-                dd_ljd*ffp->iparams[ti*ffp->atnr+tj].lj.c6 +
-                dd_ljr*ffp->iparams[ti*ffp->atnr+tj].lj.c12 +
-                dd_el*att[i].prop.q*att[j].prop.q;
+            md1 =
+                md1_ljd*ffp->iparams[ti*ffp->atnr+tj].lj.c6 +
+                md1_ljr*ffp->iparams[ti*ffp->atnr+tj].lj.c12 +
+                md1_el*att[i].prop.q*att[j].prop.q;
+
+            /* d2V/dr2 at the cut-off for LJ + Coulomb */
+            d2 =
+                d2_ljd*ffp->iparams[ti*ffp->atnr+tj].lj.c6 +
+                d2_ljr*ffp->iparams[ti*ffp->atnr+tj].lj.c12 +
+                d2_el*att[i].prop.q*att[j].prop.q;
+
+            /* -d3V/dr3 at the cut-off for LJ, we neglect Coulomb */
+            md3 =
+                md3_ljd*ffp->iparams[ti*ffp->atnr+tj].lj.c6 +
+                md3_ljr*ffp->iparams[ti*ffp->atnr+tj].lj.c12;
 
             rsh    = r_buffer;
             sc_fac = 1.0;
@@ -625,21 +630,25 @@ static real ener_drift(const verletbuf_atomtype_t *att, int natt,
             c_exp  = exp(-rsh*rsh/(2*s2))/sqrt(2*M_PI);
             c_erfc = 0.5*gmx_erfc(rsh/(sqrt(2*s2)));
             s      = sqrt(s2);
+            rsh2   = rsh*rsh;
 
             pot1 = sc_fac*
-                md/2*((rsh*rsh + s2)*c_erfc - rsh*s*c_exp);
+                md1/2*((rsh2 + s2)*c_erfc - rsh*s*c_exp);
             pot2 = sc_fac*
-                dd/6*(s*(rsh*rsh + 2*s2)*c_exp - rsh*(rsh*rsh + 3*s2)*c_erfc);
-            pot = pot1 + pot2;
+                d2/6*(s*(rsh2 + 2*s2)*c_exp - rsh*(rsh2 + 3*s2)*c_erfc);
+            pot3 =
+                md3/24*((rsh2*rsh2 + 6*rsh2*s2 + 3*s2*s2)*c_erfc - rsh*s*(rsh2 + 5*s2)*c_exp);
+            pot = pot1 + pot2 + pot3;
 
             if (gmx_debug_at)
             {
-                fprintf(debug, "n %d %d d s %.3f %.3f %.3f %.3f con %d md %8.1e dd %8.1e pot1 %8.1e pot2 %8.1e pot %8.1e\n",
+                fprintf(debug, "n %d %d d s %.3f %.3f %.3f %.3f con %d -d1 %8.1e d2 %8.1e -d3 %8.1e pot1 %8.1e pot2 %8.1e pot3 %8.1e pot %8.1e\n",
                         att[i].n, att[j].n,
                         sqrt(s2i_2d), sqrt(s2i_3d),
                         sqrt(s2j_2d), sqrt(s2j_3d),
                         att[i].prop.bConstr+att[j].prop.bConstr,
-                        md, dd, pot1, pot2, pot);
+                        md1, d2, md3,
+                        pot1, pot2, pot3, pot);
             }
 
             /* Multiply by the number of atom pairs */
@@ -715,6 +724,26 @@ static real surface_frac(int cluster_size, real particle_distance, real rlist)
     return area_rel/cluster_size;
 }
 
+/* Returns the negative of the third derivative of a potential r^-p
+ * with a force-switch function, evaluated at the cut-off rc.
+ */
+static real md3_force_switch(real p, real rswitch, real rc)
+{
+    /* The switched force function is:
+     * p*r^-(p+1) + a*(r - rswitch)^2 + b*(r - rswitch)^3
+     */
+    real a, b;
+    real md3_pot, md3_sw;
+
+    a = -((p + 4)*rc - (p + 1)*rswitch)/(pow(rc, p+2)*pow(rc-rswitch, 2));
+    b =  ((p + 3)*rc - (p + 1)*rswitch)/(pow(rc, p+2)*pow(rc-rswitch, 3));
+
+    md3_pot = (p + 2)*(p + 1)*p*pow(rc, p+3);
+    md3_sw  = 2*a + 6*b*(rc - rswitch);
+
+    return md3_pot + md3_sw;
+}
+
 void calc_verlet_buffer_size(const gmx_mtop_t *mtop, real boxvol,
                              const t_inputrec *ir,
                              real reference_temperature,
@@ -731,7 +760,9 @@ void calc_verlet_buffer_size(const gmx_mtop_t *mtop, real boxvol,
     verletbuf_atomtype_t *att  = NULL;
     int                   natt = -1, i;
     double                reppow;
-    real                  md_ljd,  dd_ljd, md_ljr, dd_ljr, md_el, dd_el;
+    real                  md1_ljd, d2_ljd, md3_ljd;
+    real                  md1_ljr, d2_ljr, md3_ljr;
+    real                  md1_el,  d2_el;
     real                  elfac;
     real                  kT_fac, mass_min;
     int                   ib0, ib1, ib;
@@ -807,46 +838,41 @@ void calc_verlet_buffer_size(const gmx_mtop_t *mtop, real boxvol,
         fprintf(debug, "energy drift atom types: %d\n", natt);
     }
 
-    reppow = mtop->ffparams.reppow;
-    md_ljd = 0;
-    dd_ljd = 0;
-    md_ljr = 0;
-    dd_ljr = 0;
+    reppow   = mtop->ffparams.reppow;
+    md1_ljd  = 0;
+    d2_ljd   = 0;
+    md3_ljd  = 0;
+    md1_ljr  = 0;
+    d2_ljr   = 0;
+    md3_ljr  = 0;
     if (ir->vdwtype == evdwCUT)
     {
-        real sw_range, sw_range2;
+        real sw_range, md3_pswf;
 
         switch (ir->vdw_modifier)
         {
             case eintmodNONE:
             case eintmodPOTSHIFT:
                 /* -dV/dr of -r^-6 and r^-reppow */
-                md_ljd =     -6*pow(ir->rvdw, -7.0);
-                md_ljr = reppow*pow(ir->rvdw, -(reppow+1));
-                /* The contribution of the second derivative is negligible */
+                md1_ljd =     -6*pow(ir->rvdw, -7.0);
+                md1_ljr = reppow*pow(ir->rvdw, -(reppow+1));
+                /* The contribution of the higher derivatives is negligible */
                 break;
             case eintmodFORCESWITCH:
-                /* At the cut-off: V=V'=V''=0.
-                 * We choose to approximate the potential over the switch
-                 * region using a linear force, thus quadratic potential.
-                 * This is a tight overestimate for too short switching
-                 * regions and not more than a factor 2 higher otherwise.
-                 */
-                sw_range = ir->rvdw - ir->rvdw_switch;
-                dd_ljd   =     -6*pow(ir->rvdw_switch, -7.0       )/sw_range;
-                dd_ljr   = reppow*pow(ir->rvdw_switch, -(reppow+1))/sw_range;
+                /* At the cut-off: V=V'=V''=0, so we use only V''' */
+                md3_ljd  = -md3_force_switch(6.0,    ir->rvdw_switch, ir->rvdw);
+                md3_ljr  =  md3_force_switch(reppow, ir->rvdw_switch, ir->rvdw);
                 break;
             case eintmodPOTSWITCH:
                 /* At the cut-off: V=V'=V''=0.
-                 * We choose to approximate the potential over the switch
-                 * region using a quadratic potential.
-                 * This is an overestimate close to the cut-off and can be
-                 * a slight underestimate close to rswitch.
+                 * V''' is given by the original potential times
+                 * the third derivative of the switch function.
                  */
                 sw_range  = ir->rvdw - ir->rvdw_switch;
-                sw_range2 = sw_range*sw_range;
-                dd_ljd    =      -12*pow(ir->rvdw_switch, -6.0   )/sw_range2;
-                dd_ljr    = 2*reppow*pow(ir->rvdw_switch, -reppow)/sw_range2;
+                md3_pswf  = 60.0*pow(sw_range, -3.0);
+
+                md3_ljd   = -pow(ir->rvdw, -6.0   )*md3_pswf;
+                md3_ljr   =  pow(ir->rvdw, -reppow)*md3_pswf;
                 break;
             default:
                 gmx_incons("Unimplemented VdW modifier");
@@ -862,9 +888,9 @@ void calc_verlet_buffer_size(const gmx_mtop_t *mtop, real boxvol,
         br4      = br2*br2;
         br6      = br4*br2;
         /* -dV/dr of g(br)*r^-6 [where g(x) = exp(-x^2)(1+x^2+x^4/2), see LJ-PME equations in manual] and r^-reppow */
-        md_ljd   = -exp(-br2)*(br6 + 3.0*br4 + 6.0*br2 + 6.0)*pow(r, -7.0);
-        md_ljr   = reppow*pow(r, -(reppow+1));
-        /* The contribution of the second derivative is negligible */
+        md1_ljd  = -exp(-br2)*(br6 + 3.0*br4 + 6.0*br2 + 6.0)*pow(r, -7.0);
+        md1_ljr  = reppow*pow(r, -(reppow+1));
+        /* The contribution of the higher derivatives is negligible */
     }
     else
     {
@@ -874,8 +900,8 @@ void calc_verlet_buffer_size(const gmx_mtop_t *mtop, real boxvol,
     elfac = ONE_4PI_EPS0/ir->epsilon_r;
 
     /* Determine md=-dV/dr and dd=d^2V/dr^2 */
-    md_el = 0;
-    dd_el = 0;
+    md1_el = 0;
+    d2_el  = 0;
     if (ir->coulombtype == eelCUT || EEL_RF(ir->coulombtype))
     {
         real eps_rf, k_rf;
@@ -901,19 +927,19 @@ void calc_verlet_buffer_size(const gmx_mtop_t *mtop, real boxvol,
 
         if (eps_rf > 0)
         {
-            md_el = elfac*(pow(ir->rcoulomb, -2.0) - 2*k_rf*ir->rcoulomb);
+            md1_el = elfac*(pow(ir->rcoulomb, -2.0) - 2*k_rf*ir->rcoulomb);
         }
-        dd_el = elfac*(2*pow(ir->rcoulomb, -3.0) + 2*k_rf);
+        d2_el      = elfac*(2*pow(ir->rcoulomb, -3.0) + 2*k_rf);
     }
     else if (EEL_PME(ir->coulombtype) || ir->coulombtype == eelEWALD)
     {
         real b, rc, br;
 
-        b     = calc_ewaldcoeff_q(ir->rcoulomb, ir->ewald_rtol);
-        rc    = ir->rcoulomb;
-        br    = b*rc;
-        md_el = elfac*(b*exp(-br*br)*M_2_SQRTPI/rc + gmx_erfc(br)/(rc*rc));
-        dd_el = elfac/(rc*rc)*(2*b*(1 + br*br)*exp(-br*br)*M_2_SQRTPI + 2*gmx_erfc(br)/rc);
+        b      = calc_ewaldcoeff_q(ir->rcoulomb, ir->ewald_rtol);
+        rc     = ir->rcoulomb;
+        br     = b*rc;
+        md1_el = elfac*(b*exp(-br*br)*M_2_SQRTPI/rc + gmx_erfc(br)/(rc*rc));
+        d2_el  = elfac/(rc*rc)*(2*b*(1 + br*br)*exp(-br*br)*M_2_SQRTPI + 2*gmx_erfc(br)/rc);
     }
     else
     {
@@ -974,9 +1000,9 @@ void calc_verlet_buffer_size(const gmx_mtop_t *mtop, real boxvol,
 
     if (debug)
     {
-        fprintf(debug, "md_ljd %9.2e dd_ljd %9.2e\n", md_ljd, dd_ljd);
-        fprintf(debug, "md_ljr %9.2e dd_ljr %9.2e\n", md_ljr, dd_ljr);
-        fprintf(debug, "md_el  %9.2e dd_el  %9.2e\n", md_el, dd_el);
+        fprintf(debug, "md1_ljd %9.2e d2_ljd %9.2e md3_ljd %9.2e\n", md1_ljd, d2_ljd, md3_ljd);
+        fprintf(debug, "md1_ljr %9.2e d2_ljr %9.2e md3_ljr %9.2e\n", md1_ljr, d2_ljr, md3_ljr);
+        fprintf(debug, "md1_el  %9.2e d2_el  %9.2e\n", md1_el, d2_el);
         fprintf(debug, "sqrt(kT_fac) %f\n", sqrt(kT_fac));
         fprintf(debug, "mass_min %f\n", mass_min);
     }
@@ -996,9 +1022,9 @@ void calc_verlet_buffer_size(const gmx_mtop_t *mtop, real boxvol,
          */
         drift = ener_drift(att, natt, &mtop->ffparams,
                            kT_fac,
-                           md_ljd, dd_ljd,
-                           md_ljr, dd_ljr,
-                           md_el, dd_el,
+                           md1_ljd, d2_ljd, md3_ljd,
+                           md1_ljr, d2_ljr, md3_ljr,
+                           md1_el,  d2_el,
                            rb,
                            rl, boxvol);
 
index 8bef766c87ec6a9ddc881661c9b5caeb96fc5c06..5675b2fab01740caf2615bfad14419fd92ea47ad 100644 (file)
@@ -1200,6 +1200,13 @@ void check_ir(const char *mdparin, t_inputrec *ir, t_gromppopts *opts,
     {
         sprintf(err_buf, "With switched vdw forces or potentials, rvdw-switch must be < rvdw");
         CHECK(ir->rvdw_switch >= ir->rvdw);
+
+        if (ir->rvdw_switch < 0.5*ir->rvdw)
+        {
+            sprintf(warn_buf, "You are applying a switch function to vdw forces or potentials from %g to %g nm, which is more than half the interaction range, whereas switch functions are intended to act only close to the cut-off.",
+                    ir->rvdw_switch, ir->rvdw);
+            warning_note(wi, warn_buf);
+        }
     }
     else if (ir->vdwtype == evdwCUT || ir->vdwtype == evdwPME)
     {
index f5a231849e92a69d9c5499204fb348edcf1dcb80..cef2d70117b6d040895c7055adab9fbb0d05fbce 100644 (file)
@@ -350,7 +350,7 @@ static void cmp_idef(FILE *fp, t_idef *id1, t_idef *id2, real ftol, real abstol)
     {
         cmp_int(fp, "idef->ntypes", -1, id1->ntypes, id2->ntypes);
         cmp_int(fp, "idef->atnr",  -1, id1->atnr, id2->atnr);
-        for (i = 0; (i < id1->ntypes); i++)
+        for (i = 0; (i < min(id1->ntypes, id2->ntypes)); i++)
         {
             sprintf(buf1, "idef->functype[%d]", i);
             sprintf(buf2, "idef->iparam[%d]", i);