Merge release-4-6 into master
authorRoland Schulz <roland@utk.edu>
Sun, 20 Jan 2013 23:41:51 +0000 (18:41 -0500)
committerRoland Schulz <roland@utk.edu>
Sun, 20 Jan 2013 23:49:12 +0000 (18:49 -0500)
Conflicts:
CMakeLists.txt (OPENMM, regressiontests)
COPYING (OpenMM, renumbering)
cmake/FortranCInterface.cmake
include/CMakeLists.txt (F77, not needed)
include/disre.h (rename detection failed - no conflict)
include/types/iteratedconstraints.h (rename detection failed -
     no conflict)

both here and src/kernel new - only contrib kep:
src/contrib/md_openmm.c
src/contrib/md_openmm.h
src/contrib/openmm_wrapper.cpp
src/contrib/openmm_wrapper.h
src/kernel/md_openmm.c
src/kernel/openmm_wrapper.cpp
src/kernel/openmm_wrapper.h
src/programs/mdrun/md_openmm.c
src/programs/mdrun/openmm_wrapper.cpp
src/programs/mdrun/openmm_wrapper.h
src/programs/mdrun/runner.c

src/gmxlib/rando.c (rename detection failed - no conflict)
src/gromacs/gmxlib/main.c
src/gromacs/gmxlib/string2.c
src/gromacs/gmxlib/tpxio.c (incrememted to 92 - updated if)
src/gromacs/gmxlib/vmdio.c
src/gromacs/legacyheaders/domdec.h (removed export)
src/gromacs/legacyheaders/gmx_omp_nthreads.h
src/gromacs/legacyheaders/main.h
src/gromacs/legacyheaders/names.h (removed export)
src/gromacs/linearalgebra/eigensolver.c
src/gromacs/linearalgebra/gmx_arpack.c
src/gromacs/linearalgebra/gmx_arpack.h
src/gromacs/linearalgebra/gmx_lapack.h (removed #define F77)
src/kernel/CMakeLists.txt (OpenMM changes moved to
       src/programs/mdrun/CMakeLists.txt)
src/tools/CMakeLists.txt
src/tools/gmx_bar.c
src/tools/gmx_covar.c
tests/CMakeLists.txt (fixed paths)

Extra changes:
src/config.h.cmakein (removed double gmx_header_config.h include)
src/gromacs/CMakeLists.txt (removed OpenMM )
        src/gromacs/linearalgebra/gmx_blas.h (removed #define F77)

Change-Id: I04fb402d503c8d5d97ee364c598e0f474956052f

124 files changed:
CMakeLists.txt
COPYING
INSTALL-GPU [deleted file]
README-GPU [deleted file]
admin/installguide/installguide.tex
cmake/FindFFTW.cmake
cmake/FortranCInterface.cmake [deleted file]
cmake/gmxCFlags.cmake
cmake/gmxGetCompilerInfo.cmake
cmake/gmxManageGPU.cmake
scripts/completion.bash
scripts/completion.csh
scripts/completion.zsh
share/html/online/mdp_opt.html
src/config.h.cmakein
src/contrib/BuildMdrunOpenMM.cmake [new file with mode: 0644]
src/contrib/CMakeLists.txt
src/contrib/FindOpenMM.cmake [moved from cmake/FindOpenMM.cmake with 100% similarity]
src/contrib/md_openmm.c [moved from src/programs/mdrun/md_openmm.c with 91% similarity]
src/contrib/md_openmm.h [new file with mode: 0644]
src/contrib/mdrun_openmm.c [new file with mode: 0644]
src/contrib/openmm_gpu_utils.cu [new file with mode: 0644]
src/contrib/openmm_gpu_utils.h [new file with mode: 0644]
src/contrib/openmm_wrapper.cpp [moved from src/programs/mdrun/openmm_wrapper.cpp with 99% similarity]
src/contrib/openmm_wrapper.h [new file with mode: 0644]
src/contrib/runner_openmm.c [new file with mode: 0644]
src/gromacs/CMakeLists.txt
src/gromacs/gmxlib/cinvsqrtdata.c
src/gromacs/gmxlib/disre.c
src/gromacs/gmxlib/gmx_detect_hardware.c
src/gromacs/gmxlib/gmx_omp_nthreads.c
src/gromacs/gmxlib/gpu_utils/gpu_utils.cu
src/gromacs/gmxlib/libxdrf.c
src/gromacs/gmxlib/main.c
src/gromacs/gmxlib/mtop_util.c
src/gromacs/gmxlib/names.c
src/gromacs/gmxlib/network.c
src/gromacs/gmxlib/nonbonded/nb_kernel_avx_128_fma_double/nb_kernel_ElecGB_VdwCSTab_GeomP1P1_avx_128_fma_double.c
src/gromacs/gmxlib/nonbonded/nb_kernel_avx_128_fma_double/nb_kernel_ElecGB_VdwLJ_GeomP1P1_avx_128_fma_double.c
src/gromacs/gmxlib/nonbonded/nb_kernel_avx_128_fma_double/nb_kernel_ElecGB_VdwNone_GeomP1P1_avx_128_fma_double.c
src/gromacs/gmxlib/nonbonded/nb_kernel_avx_128_fma_double/nb_kernel_template_avx_128_fma_double.pre
src/gromacs/gmxlib/nonbonded/nb_kernel_avx_128_fma_single/nb_kernel_ElecGB_VdwCSTab_GeomP1P1_avx_128_fma_single.c
src/gromacs/gmxlib/nonbonded/nb_kernel_avx_128_fma_single/nb_kernel_ElecGB_VdwLJ_GeomP1P1_avx_128_fma_single.c
src/gromacs/gmxlib/nonbonded/nb_kernel_avx_128_fma_single/nb_kernel_ElecGB_VdwNone_GeomP1P1_avx_128_fma_single.c
src/gromacs/gmxlib/nonbonded/nb_kernel_avx_128_fma_single/nb_kernel_template_avx_128_fma_single.pre
src/gromacs/gmxlib/nonbonded/nb_kernel_avx_256_double/nb_kernel_ElecGB_VdwCSTab_GeomP1P1_avx_256_double.c
src/gromacs/gmxlib/nonbonded/nb_kernel_avx_256_double/nb_kernel_ElecGB_VdwLJ_GeomP1P1_avx_256_double.c
src/gromacs/gmxlib/nonbonded/nb_kernel_avx_256_double/nb_kernel_ElecGB_VdwNone_GeomP1P1_avx_256_double.c
src/gromacs/gmxlib/nonbonded/nb_kernel_avx_256_double/nb_kernel_template_avx_256_double.pre
src/gromacs/gmxlib/nonbonded/nb_kernel_avx_256_single/nb_kernel_ElecGB_VdwCSTab_GeomP1P1_avx_256_single.c
src/gromacs/gmxlib/nonbonded/nb_kernel_avx_256_single/nb_kernel_ElecGB_VdwLJ_GeomP1P1_avx_256_single.c
src/gromacs/gmxlib/nonbonded/nb_kernel_avx_256_single/nb_kernel_ElecGB_VdwNone_GeomP1P1_avx_256_single.c
src/gromacs/gmxlib/nonbonded/nb_kernel_avx_256_single/nb_kernel_template_avx_256_single.pre
src/gromacs/gmxlib/nonbonded/nb_kernel_c/nb_kernel_ElecGB_VdwLJ_GeomP1P1_c.c
src/gromacs/gmxlib/nonbonded/nb_kernel_sse2_double/nb_kernel_ElecGB_VdwCSTab_GeomP1P1_sse2_double.c
src/gromacs/gmxlib/nonbonded/nb_kernel_sse2_double/nb_kernel_ElecGB_VdwLJ_GeomP1P1_sse2_double.c
src/gromacs/gmxlib/nonbonded/nb_kernel_sse2_double/nb_kernel_ElecGB_VdwNone_GeomP1P1_sse2_double.c
src/gromacs/gmxlib/nonbonded/nb_kernel_sse2_double/nb_kernel_template_sse2_double.pre
src/gromacs/gmxlib/nonbonded/nb_kernel_sse2_single/nb_kernel_ElecGB_VdwCSTab_GeomP1P1_sse2_single.c
src/gromacs/gmxlib/nonbonded/nb_kernel_sse2_single/nb_kernel_ElecGB_VdwLJ_GeomP1P1_sse2_single.c
src/gromacs/gmxlib/nonbonded/nb_kernel_sse2_single/nb_kernel_ElecGB_VdwNone_GeomP1P1_sse2_single.c
src/gromacs/gmxlib/nonbonded/nb_kernel_sse2_single/nb_kernel_template_sse2_single.pre
src/gromacs/gmxlib/nonbonded/nb_kernel_sse4_1_double/nb_kernel_ElecGB_VdwCSTab_GeomP1P1_sse4_1_double.c
src/gromacs/gmxlib/nonbonded/nb_kernel_sse4_1_double/nb_kernel_ElecGB_VdwLJ_GeomP1P1_sse4_1_double.c
src/gromacs/gmxlib/nonbonded/nb_kernel_sse4_1_double/nb_kernel_ElecGB_VdwNone_GeomP1P1_sse4_1_double.c
src/gromacs/gmxlib/nonbonded/nb_kernel_sse4_1_double/nb_kernel_template_sse4_1_double.pre
src/gromacs/gmxlib/nonbonded/nb_kernel_sse4_1_single/nb_kernel_ElecGB_VdwCSTab_GeomP1P1_sse4_1_single.c
src/gromacs/gmxlib/nonbonded/nb_kernel_sse4_1_single/nb_kernel_ElecGB_VdwLJ_GeomP1P1_sse4_1_single.c
src/gromacs/gmxlib/nonbonded/nb_kernel_sse4_1_single/nb_kernel_ElecGB_VdwNone_GeomP1P1_sse4_1_single.c
src/gromacs/gmxlib/nonbonded/nb_kernel_sse4_1_single/nb_kernel_template_sse4_1_single.pre
src/gromacs/gmxlib/orires.c
src/gromacs/gmxlib/tpxio.c
src/gromacs/gmxlib/txtdump.c
src/gromacs/gmxpreprocess/readir.c
src/gromacs/legacyheaders/disre.h
src/gromacs/legacyheaders/domdec.h
src/gromacs/legacyheaders/gmx_omp_nthreads.h
src/gromacs/legacyheaders/gpu_utils.h
src/gromacs/legacyheaders/main.h
src/gromacs/legacyheaders/mdebin.h
src/gromacs/legacyheaders/mdrun.h
src/gromacs/legacyheaders/names.h
src/gromacs/legacyheaders/types/hw_info.h
src/gromacs/legacyheaders/types/inputrec.h
src/gromacs/legacyheaders/types/iteratedconstraints.h
src/gromacs/linearalgebra/eigensolver.c
src/gromacs/linearalgebra/gmx_arpack.c
src/gromacs/linearalgebra/gmx_arpack.h
src/gromacs/linearalgebra/gmx_blas.h
src/gromacs/linearalgebra/gmx_lapack.h
src/gromacs/mdlib/coupling.c
src/gromacs/mdlib/domdec.c
src/gromacs/mdlib/forcerec.c
src/gromacs/mdlib/genborn.c
src/gromacs/mdlib/iteratedconstraints.c
src/gromacs/mdlib/mdebin.c
src/gromacs/mdlib/mdebin_bar.c
src/gromacs/mdlib/mdebin_bar.h
src/gromacs/mdlib/minimize.c
src/gromacs/mdlib/nbnxn_cuda/nbnxn_cuda.cu
src/gromacs/mdlib/nbnxn_cuda/nbnxn_cuda_data_mgmt.cu
src/gromacs/mdlib/nbnxn_cuda/nbnxn_cuda_kernel.cuh
src/gromacs/mdlib/nbnxn_search.c
src/gromacs/mdlib/qm_gamess.c
src/gromacs/mdlib/qm_mopac.c
src/gromacs/mdlib/update.c
src/programs/gmxcheck/tpbcmp.c
src/programs/gmxdump/gmxdump.c
src/programs/mdrun/CMakeLists.txt
src/programs/mdrun/md.c
src/programs/mdrun/md_openmm.h [deleted file]
src/programs/mdrun/mdrun.c
src/programs/mdrun/membed.c
src/programs/mdrun/openmm_wrapper.h [deleted file]
src/programs/mdrun/pme_loadbal.c
src/programs/mdrun/repl_ex.c
src/programs/mdrun/runner.c
src/tools/gmx_bar.c
src/tools/gmx_disre.c
src/tools/gmx_energy.c
src/tools/gmx_membed.c
src/tools/gmx_trjconv.c
src/tools/gmx_tune_pme.c
tests/CMakeLists.txt

index c81554dda3d8c8b79af41ff4acaea356381bd1d0..6c8f22e99a1089036b0c7b61a3fbfcf8082558e1 100644 (file)
@@ -193,12 +193,16 @@ mark_as_advanced(GMX_SKIP_DEFAULT_CFLAGS)
 include(CheckCCompilerFlag)
 include(CheckCXXCompilerFlag)
 
+# Get compiler version information, needs to be done early as check that depend
+# on compiler verison follow below.
+include(gmxGetCompilerInfo)
+get_compiler_version()
+
 # First exclude compilers known to not work with OpenMP although claim to support it:
 # gcc 4.2.1 and gcc-llvm 4.2.1 (also claims to be 4.2.1) on Mac OS X
 # This fixes redmine 900 and needs to run before OpenMP flags are set below.
-message("CMAKE_COMPILER_IS_GNUCC: ${CMAKE_COMPILER_IS_GNUCC}")
 if (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND
-    CMAKE_COMPILER_IS_GNUCC AND C_COMPILER_VERSION VERSION_LESS 4.3)
+    (CMAKE_COMPILER_IS_GNUCC AND C_COMPILER_VERSION AND C_COMPILER_VERSION VERSION_LESS 4.3))
     message(STATUS "OpenMP multithreading not supported with gcc/llvm-gcc 4.2 on Mac OS X, disabled")
     set(GMX_OPENMP OFF CACHE BOOL
         "OpenMP multithreading not not supported with gcc/llvm-gcc 4.2 on Mac OS X, disabled!" FORCE)
@@ -235,9 +239,6 @@ endif()
 include(gmxCFlags)
 gmx_c_flags()
 
-include(gmxGetCompilerInfo)
-get_compiler_version()
-
 # gcc 4.4.x is buggy and crashes when compiling some files with O3 and OpenMP on.
 # Detect here whether applying a workaround is needed and will apply it later
 # on the affected files.
@@ -278,10 +279,6 @@ if (GMX_DEFAULT_SUFFIX)
     set (GMX_BINARY_SUFFIX "${GMX_BINARY_SUFFIX}_d")
     set (GMX_LIBS_SUFFIX "${GMX_LIBS_SUFFIX}_d")
   endif(GMX_DOUBLE)
-  if (GMX_OPENMM)
-    set (GMX_BINARY_SUFFIX "-openmm")
-    set (GMX_LIBS_SUFFIX "_openmm")
-  endif(GMX_OPENMM)
   mark_as_advanced(FORCE GMX_BINARY_SUFFIX GMX_LIBS_SUFFIX)
   if (NOT SUFFIX_QUIETLY)
     message(STATUS "Using default binary suffix: \"${GMX_BINARY_SUFFIX}\"")
@@ -304,53 +301,6 @@ if(GMX_SOFTWARE_INVSQRT)
   set(PKG_CFLAGS "${PKG_CFLAGS} -DGMX_SOFTWARE_INVSQRT")
 endif(GMX_SOFTWARE_INVSQRT)
 
-#######################################################################
-# Check for options incompatible with OpenMM build                    #
-#######################################################################
-if(GMX_OPENMM)
-    # we'll use the built-in fft to avoid unnecessary dependencies
-    string(TOUPPER ${GMX_FFT_LIBRARY} GMX_FFT_LIBRARY)
-    if(NOT ${GMX_FFT_LIBRARY} STREQUAL "FFTPACK")
-        message(STATUS "No external FFT libraries needed for the OpenMM build, switching to fftpack!")
-        set(GMX_FFT_LIBRARY "fftpack" CACHE STRING 
-               "No external FFT libraries needed for the OpenMM build, switching to  fftpack!" FORCE)
-    endif()
-    if(GMX_MPI)
-        message(FATAL_ERROR "The OpenMM build is not compatible with MPI!")
-    endif(GMX_MPI)
-    if(GMX_THREAD_MPI)
-        message(STATUS "Thread-MPI not compatible with OpenMM, disabled!")
-        set(GMX_THREAD_MPI OFF CACHE BOOL
-               "Thread-MPI not compatible with OpenMM build, disabled!" FORCE)
-    endif(GMX_THREAD_MPI)
-    if(GMX_OPENMP)
-        message(STATUS "OpenMP multithreading not compatible with OpenMM, disabled")
-        set(GMX_OPENMP OFF CACHE BOOL
-            "OpenMP multithreading not compatible with OpenMM, disabled!" FORCE)
-    endif()
-    if(GMX_SOFTWARE_INVSQRT)
-        set(GMX_SOFTWARE_INVSQRT OFF CACHE STRING 
-                "The OpenMM build does not need GROMACS software 1/sqrt!" FORCE)
-    endif(GMX_SOFTWARE_INVSQRT)
-    string(TOUPPER ${GMX_CPU_ACCELERATION} GMX_CPU_ACCELERATION)
-    if(NOT GMX_CPU_ACCELERATION STREQUAL "NONE")
-        message(STATUS "Switching off CPU-based acceleration, the OpenMM build does not support/need any!")
-        set(GMX_CPU_ACCELERATION "None" CACHE STRING
-            "Switching off CPU-based acceleration, the OpenMM build does not support/need any!" FORCE)
-    endif()
-    if(GMX_FAHCORE)
-        message(FATAL_ERROR "The OpenMM build does not support FAH build!")
-    endif(GMX_FAHCORE)
-    if(GMX_DOUBLE)
-        message(FATAL_ERROR  "The OpenMM-build does not support double precision calculations!")
-    endif()
-    # mark as advanced the unused variables
-    mark_as_advanced(FORCE GMX_CPU_ACCELERATION GMX_MPI GMX_FFT_LIBRARY 
-        GMX_QMMM_PROGRAM GMX_THREAD_MPI GMX_DOUBLE)
-else(GMX_OPENMM)
-     mark_as_advanced(CLEAR GMX_CPU_ACCELERATION GMX_MPI GMX_FFT_LIBRARY 
-        GMX_QMMM_PROGRAM GMX_THREAD_MPI GMX_DOUBLE)
-endif(GMX_OPENMM)
 
 
 ########################################################################
@@ -544,16 +494,6 @@ else(GMX_THREAD_MPI)
     tmpi_get_source_list(THREAD_MPI_SRC CXX NOMPI)
 endif(GMX_THREAD_MPI)
 
-if(GMX_OPENMM)
-    set(CUDA_BUILD_EMULATION OFF)
-    find_package(CUDA 3.1 REQUIRED)
-    add_definitions(-DGMX_OPENMM)
-    if(CMAKE_BUILD_TYPE STREQUAL "DEBUG")    
-        set(CUDA_VERBOSE_BUILD ON)
-    endif()
-    find_package(OpenMM) 
-endif(GMX_OPENMM)
-
 if(GMX_GPU)
     # now that we have detected the dependencies, do the second configure pass
     gmx_gpu_setup()
@@ -755,7 +695,7 @@ elseif(${GMX_CPU_ACCELERATION} STREQUAL "SSE4.1")
         endif()
     endif(NOT GNU_SSE4_CFLAG AND NOT MSVC_SSE4_CFLAG)
 
-    GMX_TEST_CXXFLAG(GNU_SSE4_CXXFLAG "-msse4.1" GROMACS_CXX_FLAG)
+    GMX_TEST_CXXFLAG(GNU_SSE4_CXXFLAG "-msse4.1" ACCELERATION_CXX_FLAGS)
     if (NOT GNU_SSE4_CXXFLAG AND GMX_NATIVE_WINDOWS)
         GMX_TEST_CXXFLAG(MSVC_SSE4_CXXFLAG "/arch:SSE4.1" ACCELERATION_CXX_FLAGS)
     endif(NOT GNU_SSE4_CXXFLAG AND GMX_NATIVE_WINDOWS)
@@ -917,7 +857,7 @@ else(${GMX_QMMM_PROGRAM} STREQUAL "GAUSSIAN")
     MESSAGE(FATAL_ERROR "Invalid QM/MM program option: ${GMX_QMMM_PROGRAM}. Choose one of: Gaussian, Mopac, Gamess, Orca, None")
 endif(${GMX_QMMM_PROGRAM} STREQUAL "GAUSSIAN")
 
-# Process FFT library settings - if not OpenMM build 
+# Process FFT library settings
 string(TOUPPER ${GMX_FFT_LIBRARY} ${GMX_FFT_LIBRARY})
 set(PKG_FFT "")
 set(PKG_FFT_LIBS "")
@@ -1177,8 +1117,17 @@ ADD_CUSTOM_TARGET(uninstall
 
 include(CTest)
 mark_as_advanced(BUILD_TESTING)
+#gmxtests target builds all binaries required for running gmxtest
+add_custom_target(gmxtests DEPENDS grompp mdrun pdb2gmx gmxcheck gmx)
 IF(BUILD_TESTING)
     enable_testing()
     add_subdirectory(tests)
+    if(REGRESSIONTEST_PATH)
+        #check target builds all to run tests and the runs tests
+        add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure)
+        add_dependencies(check gmxtests)
+    else()
+        add_custom_target(check COMMAND ${CMAKE_COMMAND} -E echo "WARNING: No tests are run. Running the tests requires either of the cmake variables REGRESSIONTEST_PATH or REGRESSIONTEST_DOWNLOAD to be set.")
+    endif()
 ENDIF()
 
diff --git a/COPYING b/COPYING
index d180161274d7785335c0556c42ab2ef4e60e2644..93293d42f28d0514cddbf4f3030a6f5487be992c 100644 (file)
--- a/COPYING
+++ b/COPYING
@@ -13,9 +13,8 @@ This file contains the licenses for:
  5. thread_mpi
  6. Blas
  7. Lapack
- 8. OpenMM (binary distributions only)
- 9. Subset of Boost C++ library
-10. Google Test and Google Mock
+ 8. Subset of Boost C++ library
+ 9. Google Test and Google Mock
 
 1. GROMACS
 ====================================
@@ -557,13 +556,8 @@ better idea to use the full reference implementation.
 
 Erik Lindahl, 2008-10-07.
 
-8. OpenMM (binary distributions only)
-=====================================
 
-There are several licenses which cover different parts of OpenMM as described
-in the file openmm/licenses/Licenses.txt accompanying the binary distribution.
-
-9. Subset of Boost C++ library
+8. Subset of Boost C++ library
 ==============================
 Files: src/external/boost/boost/*
 
@@ -591,7 +585,7 @@ FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 
-10. Google Test and Google Mock
+ 9. Google Test and Google Mock
 ===============================
 Files: src/external/gmock-1.6.0/*
 
@@ -622,4 +616,4 @@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/INSTALL-GPU b/INSTALL-GPU
deleted file mode 100644 (file)
index 3b9326a..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-
-                    Welcome to GROMACS-GPU!
-
-Note: Detailed, step-by-step installation instructions as 
-well as additional information are available on the website 
-http://www.gromacs.org/gpu
-
-
-* INSTALLING FROM BINARY DISTRIBUTION:
-
-0. Prerequisites: 
-    - OpenMM (included in the binary release)
-    - NVIDIA CUDA libraries (version >=3.1);
-    - NVIDIA driver (for details on compatiblity consult
-         http://www.nvidia.com/Download/index5.aspx);
-    - NVIDIA CUDA-enabled GPU (for compatiblity list see 
-         http://www.gromacs.org/gpu).
-
-
-1. Download and unpack the binary package for the respective 
-OS and architecture. Copy the content of the package to your 
-normal GROMACS installation directory (or to a custom location). 
-Note that as the distributed Gromacs-GPU packages do not contain 
-the entire set of tools and utilities included in a full GROMACS 
-installation. Therefore, it is recommended to have a â‰¥v4.5 
-standard Gromacs installation along the GPU accelerated one.
-e.g. on unix: 
-
-tar -xvf gromacs-4.5-GPU.tar.gz
-cp -R gromacs-4.5-GPU/* PATH_TO_GROMACS_INSTALLATION
-
-
-2. Add the openmm/lib directory to your library path, e.g. in bash:
-
-export LD_LIBRARY_PATH=PATH_TO_GROMACS/openmm/lib:$LD_LIBRARY_PATH
-
-If there are other OpenMM versions installed, make sure that the 
-supplied libraries have preference when running mdrun-gpu. 
-Also, make sure that the installed CUDA libraries match the version 
-of CUDA with which GROMACS-GPU has been compiled.
-
-
-3. Set the OPENMM_PLUGIN_DIR environment variable to contain the path 
-to the openmm/lib/plugins directory, e.g. in bash:
-
-export OPENMM_PLUGIN_DIR=PATH_TO_GROMACS/openmm/lib/plugins
-
-
-4. At this point, running the command: 
-
-PATH_TO_GROMACS/bin/mdrun-gpu -h 
-
-should display the standard mdrun help which means that all the 
-necessary libraries are accessible.
-
-
-
-* INSTALLING FROM SOURCE DISTRIBUTION:
-
-GROMACS-GPU uses a cmake build-generator and makefiles on unix. 
-All you have to do is run:
-
-cmake PATH_TO_SOURCE_DIRECTORY -DGMX_OPENMM=ON -DGMX_THREADS=OFF 
-make mdrun
-make install-mdrun
-
-
-
-* ARE YOU STILL HAVING PROBLEMS?
-
-Post it to the GROMACS mailing lists. We read these on a regular basis,
-and in many cases another user might already be familiar with the
-task you're trying to perform!
diff --git a/README-GPU b/README-GPU
deleted file mode 100644 (file)
index 057f721..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-
-               Welcome to the official version of GROMACS-GPU!
-
-
-GROMACS-GPU provides GPU-accelerated MD simulations.
-The current release uses the OpenMM library. 
-
-This release is targeted at developers and advanced users,
-and care should be taken before production use. 
-
-Installation instructions are available in the INSTALL-GPU file. 
-More details on the GPU accelerated release are available on the 
-GROMACS-GPU website: http://www.gromacs.org/gpu.
-
-See also the README file for general GROMACS information.
-
-                               * * * * *
-
-GROMACS is free software, distributed under the GNU General Public License.
-The GROMACS-GPU release however includes / relies on code covered by several 
-different licences. For details see the COPYING-GPU file.
index 34320c41ec5118241beff5ddf70d71bdf2e0a108..b73b8587940e954e7e6d877f941219cecb67944b 100644 (file)
 
 \begin{document}
 \section{Building GROMACS}
-These instructions pertain to building \gromacs{} 4.6 beta releases
-and newer. For installations instructions for old \gromacs{} versions,
-see here
+
+These instructions pertain to building \gromacs{} 4.6 and newer releases
+using our new CMake-based build system. 
+For installations instructions for old \gromacs{} versions,
+see the documentation at
 \url{http://www.gromacs.org/Documentation/Installation_Instructions_4.5}.
 
-\section{Prerequisites}
+\section{Quick and dirty installation}
 
-\subsection{Platform}
+\begin{enumerate}
+\item Get the latest version of your compiler.
+\item Check you have \cmake{} version 2.8.x or later.
+\item Unpack the \gromacs{} tarball.
+\item Make a separate build directory and change to it. 
+\item Run \cmake{} with the path to the source as an argument
+\item Run make and make install
+\end{enumerate}
+Or, as a sequence of commands to execute:
+\begin{verbatim}
+tar xfz gromacs-4.6.tar.gz
+cd gromacs-4.6
+mkdir build
+cd build
+cmake .. -DGMX_BUILD_OWN_FFTW=ON
+make
+sudo make install
+\end{verbatim}
+This will download and build first the prerequisite FFT library followed by \gromacs{}. If you already have
+FFTW installed, you can remove that argument to cmake. Overall, this build 
+of \gromacs{} will be correct and reasonably fast on the
+machine upon which \cmake{} ran. It will generally be 30-50\% faster
+than \gromacs{} 4.5.x, but if you want to get the maximum value
+for your hardware with \gromacs{}, you'll have to read further.
+Sadly, the interactions of hardware, libraries, and compilers
+are only going to continue to get more complex. 
 
+\section{Prerequisites}
+\subsection{Platform}
 \gromacs{} can be compiled for any distribution of Linux, Mac OS X,
-Windows (native, Cygwin or MinGW), BlueGene, Cray and probably others.
+Windows (native, Cygwin or MinGW), BlueGene, Cray and many other architectures.
 Technically, it can be compiled on any platform with an ANSI C
-compiler and supporting libraries, such as the GNU C library. It can
-even compile on an iPhone! Later, there will be a detailed list of
-hardware, platform and compilers upon which we do build and regression
-testing.
+compiler and supporting libraries, such as the GNU C library. However, Gromacs
+also comes with many hardware-specific extensions to provide very high performance
+on those platforms, and to enable these we have slightly more specific requirements
+since old compilers do not support new features, or they can be buggy.
 
 \subsection{Compiler}
 
@@ -76,9 +105,32 @@ recommends you get the most recent version of your preferred compiler
 for your platform (e.g. GCC 4.7 or Intel 12.0 or newer on x86
 hardware). There is a large amount of \gromacs{} code introduced in
 version 4.6 that depends on effective compiler optimization to get
-high performance - the old assembly-language routines have all
-gone. For other platforms, use the vendor's compiler, and check for
-specialized information below.
+high performance - the old raw assembly-language kernel routines are all gone.
+Unfortunately this makes \gromacs{} more sensitive to the compiler
+used, and the binary will only work on the hardware for which it is compiled,
+but the good news is that it has enabled us to significantly accelerate performance
+compared to version 4.5. 
+
+\begin{itemize}
+\item On Intel-based x86 hardware, we recommend you to use
+the Intel compiler for best performance. It is usually better at instruction
+scheduling, although it does not hurt to try gcc too. Recent versions can
+give icc a run for the money.
+\item On AMD-based x86 hardware up through the Magny-Cours architecture
+(e.g. Opteron 6100-series processors), it is worth using the Intel compiler for
+better performance, but gcc-4.7 and later are also reasonable.
+\item On the AMD Bulldozer architecture (Opteron 6200), AMD introduced fused multiply-add
+instructions and an "FMA4" instruction format not available on Intel x86 processors. Thus,
+on the most recent AMD processors you want to use gcc-4.7 or later for better performance!
+icc will only generate code for the subset also supported by Intel processors, and that
+is significantly slower right now.
+\item If you are running on Mac OS X, the best option is the Intel compiler.
+Both clang and gcc will work, but they produce lower performance and each have some
+shortcomings. Clang does not fully support OpenMP, and the current gcc ports do not
+support AVX instructions. 
+\item For all non-x86 platforms, your best option is typically to use the vendor's 
+default compiler, and check for specialized information below.
+\end{itemize}
 
 \subsubsection{Running in parallel}
 
@@ -90,14 +142,19 @@ If you wish to use the excellent new native GPU support in \gromacs,
 \nvidia{}'s \cuda{}
 \url{http://www.nvidia.com/object/cuda_home_new.html} version
 \cudaversion{} software development kit is required, and the latest
-version is encouraged. \nvidia{} GPUs with at least \nvidia{} compute
+version is strongly encouraged. \nvidia{} GPUs with at least \nvidia{} compute
 capability 2.0 are required, e.g. Fermi or Kepler cards.
 
 The GPU support from \gromacs{} version 4.5 using \openmm{}
-\url{https://simtk.org/home/openmm} is still available, also requires
-\cuda{}, and remains the only hardware-based acceleration available
-for implicit solvent simulations in \gromacs{}. This parallelization
-path may not be maintained in the future.
+\url{https://simtk.org/home/openmm} is still contained in the code,
+but in the ``user contributions'' section (\verb+src/contrib+). You
+will need to edit \verb+src/contrib/CMakeLists.txt+ to enable it. It
+also requires \cuda{}, and remains the only hardware-based
+acceleration available for implicit solvent simulations in
+\gromacs{} at the moment. However, the long-term plan is to enable 
+this functionality in core Gromacs, and not have the OpenMM
+interface supported by the \gromacs team. RIght now there might be
+some build issues for OpenMM, but they should be fixed by release 4.6.1.
 
 If you wish to run in parallel on multiple machines across a network,
 you will need to have
@@ -110,29 +167,36 @@ The \gromacs{} team recommends \openmpi{}
 \url{http://www.open-mpi.org/} version 1.4.1 (or higher), \mpich{}
 \url{http://www.mpich.org/} version 1.4.1 (or higher), or your
 hardware vendor's \mpi{} installation. The most recent version of
-either of this is likely to be the best. \lammpi{}
-\url{http://www.lam-mpi.org/} may work, but since it has been
+either of this is likely to be the best. More specialized networks
+might depend on accelerations only available in the vendor's library.
+ \lammpi{}
+\url{http://www.lam-mpi.org/} might work, but since it has been
 deprecated for years, it is not supported.
 
 In some cases, \openmp{} parallelism is an advantage for \gromacs{},
-but support for this is generally built into your compiler and you
-need to make no advance preparation for this. The performance gain you
-might achieve can vary with the compiler.
-
-It is important to examine how you will use \gromacs{} and upon what
-hardware and with what compilers in deciding which parallelization
-paths to make available. Testing the performance of different options
-is unfortunately mandatory. The days of being able to just build and
-run '\verb+mdrun+' and get decent performance by default on your
-hardware are long gone. \gromacs{} will always run correctly, and does
-a decent job of trying to maximize your performance, but if you want
-to approach close to the optimum, you will need to do some work for
-it!
+but support for this is generally built into your compiler and detected
+automatically. The one common exception is Mac OS X, where the default
+clang compiler currently does not fully support OpenMP. You can install
+gcc-4.7 instead, but the currently available binary distribution of gcc 
+uses an old system assembler that does not support AVX acceleration
+instructions. There are some examples on the internet where people have
+hacked this to work, but presently the only straightforward way to get
+both OpenMP and AVX support on Mac OS X is to get the Intel compiler.
+
+In summary, for maximum performance you will need to 
+examine how you will use \gromacs{}, what hardware you plan to run
+on, and whether you can afford a non-free compiler for slightly better
+performance. The only way to find out is unfortunately to test different
+options and parallelization schemes for the actual simulations you
+want to run. You will still get {\em good}\, performance with the default
+build and runtime options (better than in version 4.5), but if you truly
+want to push your hardware to the performance limit the days of just blindly 
+starting programs like '\verb+mdrun+' are gone. 
 
 \subsection{CMake}
 
-From version 4.6, \gromacs{} has moved to use the build system
-\cmake{}. The previous build system that used \texttt{configure} from
+From version 4.6, \gromacs{} uses the build system
+\cmake{}. The previous build system that used \verb+configure+ from
 the GNU autotools package has been removed permanently. \cmake{}
 permits the \gromacs{} team to support a very wide range of hardware,
 compilers and build configurations while continuing to provide the
@@ -140,21 +204,23 @@ portability, robustness and performance for which \gromacs{} is known.
 
 \gromacs{} requires \cmake{} version \cmakeversion{} or higher. Lower
 versions will not work. You can check whether \cmake{} is installed,
-and what version it is, with \texttt{cmake --version}. If you need to
+and what version it is, with \verb+cmake --version+. If you need to
 install \cmake{}, then first check whether your platform's package
 management system provides a suitable version, or visit
 \url{http://www.cmake.org/cmake/help/install.html} for pre-compiled
 binaries, source code and installation instructions. The \gromacs{}
 team recommends you install the most recent version of \cmake{} you
-can.
+can. If you need to compile \cmake{} yourself and have a really old environment,
+you might first have to compile a moderately recent version (say, 2.6) to
+bootstrap version 2.8. This is a one-time job, and you can find lots of
+documentation on the \cmake{} website if you run into problems.
 
 \subsection{Fast Fourier Transform library}
 
-Many simulations in \gromacs{} make extensive use of Fourier transforms,
+Many simulations in \gromacs{} make extensive use of fast Fourier transforms,
 and a software library to perform these is always required. We
 recommend \fftw{} \url{http://www.fftw.org/} (version 3 or higher
-only) or Intel's \mkl{}
-\url{http://software.intel.com/en-us/intel-mkl}.
+only) or Intel's \mkl{} \url{http://software.intel.com/en-us/intel-mkl}. 
 
 \subsubsection{\fftw{}}
 
@@ -168,43 +234,47 @@ precision, and good compiler options to use for \fftw{} when linked to
 recommends either
 \begin{itemize}
 \item that you permit the \gromacs{} installation to download and
-  build \fftw{} \fftwversion{} from source automatically
-  for you, or
+  build \fftw{} \fftwversion{} from source automatically for you (use
+  \verb+cmake -DGMX_BUILD_OWN_FFTW=ON+), or
 \item that you build \fftw{} from the source code.
 \end{itemize}
 
 If you build \fftw{} from source yourself, get the most recent version
-and follow its installation guide
-(e.g. \url{http://www.fftw.org/fftw3_doc/Installation-and-Customization.html}). Choose
-the precision (i.e. single or float vs double) to match what you will
+and follow its installation guide available from \url{http://www.fftw.org}.
+Choose the precision (i.e. single or float vs.\ double) to match what you will
 later require for \gromacs{}. There is no need to compile with
 threading or \mpi{} support, but it does no harm. On x86 hardware,
-compile \emph{only} with \texttt{--enable-sse2} (regardless of
+compile \emph{only} with \verb+--enable-sse2+ (regardless of
 precision) even if your processors can take advantage of \avx{}
-extensions to \sse{}. The way \gromacs{} uses Fourier transforms
-cannot take advantage of this feature in \fftw{} because of memory
-system performance limitations, it can degrade performance by around
-20\%, and there is no way for \gromacs{} to require the use of the
-\ssetwo{} at run time if \avx{} support has been compiled into \fftw{}.
+extensions. Since \gromacs{} uses fairly short transform lengths we
+do not benefit from the \fftw{} \avx{} acceleration, and because of
+memory system performance limitations, it can even degrade \gromacs{}
+performance by around 20\%. There is no way for \gromacs{} to
+limit the use to \ssetwo{} acceleration at run time if \avx{}
+support has been compiled into \fftw{}, so you need to set this at compile time.
 
 \subsubsection{\mkl{}}
 
 Using \mkl{} requires a set of linker flags that \gromacs{} is not
 able to detect for you, so setting up optimal linking is tricky at the
-moment. Need better documentation later.
+moment. You will need to consult your compiler documentation and
+use \verb+CMAKE_C_FLAGS+ and \verb+-DCMAKE_EXE_LINKER_FLAGS+
+accordingly.
 
 \subsection{Optional build components}
 
 \begin{itemize}
-\item A hardware-optimized \blas{} or \lapack{} library is useful for
-  some of the \gromacs{} utilities, but is not needed for running
-  simulations.
-\item The built-in \gromacs{} trajectory viewer \texttt{ngmx} requires
+\item Hardware-optimized \blas{} and \lapack{} libraries are useful for
+  a few of the \gromacs{} utilities focused on normal modes and matrix manipulation, 
+  but they does not provide any benefits for normal simulations.
+\item The built-in \gromacs{} trajectory viewer \verb+ngmx+ requires
   X11 and Motif/Lesstif libraries and header files. Generally, the
-  \gromacs{} team recommends you use third-party software for
+  \gromacs{} team rather recommends you use third-party software for
   visualization, such as \vmd{}
   \url{http://www.ks.uiuc.edu/Research/vmd/} or \pymol{}
   \url{http://www.pymol.org/}.
+\item A few \gromacs{} tools get some extra functionality when linked with the
+GNU scientific library GSL.
 \end{itemize}
 
 \section{Doing a build of \gromacs}
@@ -221,10 +291,12 @@ instructions below.
 
 \cmake{} will run many tests on your system and do its best to work
 out how to build \gromacs{} for you. If you are building \gromacs{} on
-hardware that is identical to that where you will run \texttt{mdrun},
-then you can be sure that the defaults will be pretty good. Howver, if
-you want to control aspects of the build, there's plenty of things you
-can set, too.
+hardware that is identical to that where you will run \verb+mdrun+,
+then you can be sure that the defaults will be pretty good. The build
+configuration will for instance attempt to detect the specific hardware
+instructions available in your processor. However, if
+you want to control aspects of the build, there are plenty of things you
+can set manually.
 
 The best way to use \cmake{} to configure \gromacs{} is to do an
 ``out-of-source'' build, by making another directory from which you
@@ -232,23 +304,23 @@ will run \cmake{}. This can be a subdirectory or not, it doesn't
 matter. It also means you can never corrupt your source code by trying
 to build it! So, the only required argument on the \cmake{} command
 line is the name of the directory containing the
-\texttt{CMakeLists.txt} file of the code you want to build. For
+\verb+CMakeLists.txt+ file of the code you want to build. For
 example, download the source tarball and use
-% TODO: keep up to date as we approach real releases!
+% TODO: keep up to date with new releases!
 \begin{verbatim}
-$ tar xfz gromacs-4.6-beta1-src.tgz
-$ cd gromacs-4.6-beta1
+$ tar xfz gromacs-4.6.tgz
+$ cd gromacs-4.6
 $ mkdir build-cmake
 $ cd build-cmake
 $ cmake ..
 \end{verbatim}
 
-You will see \texttt{cmake} report the results of a large number of
+You will see \verb+cmake+ report the results of a large number of
 tests on your system made by \cmake{} and by \gromacs{}. These are
-written to the \cmake{} cache, kept in \texttt{CMakeCache.txt}. You
+written to the \cmake{} cache, kept in \verb+CMakeCache.txt+. You
 can edit this file by hand, but this is not recommended because it is
 easy to reach an inconsistent state. You should not attempt to move or
-copy this file to do another build, because the paths are hard-coded
+copy this file to do another build, because file paths are hard-coded
 within it. If you mess things up, just delete this file and start
 again with '\verb+cmake+'.
 
@@ -256,59 +328,68 @@ If there's a serious problem detected at this stage, then you will see
 a fatal error and some suggestions for how to overcome it. If you're
 not sure how to deal with that, please start by searching on the web
 (most computer problems already have known solutions!) and then
-consult the \texttt{gmx-users} mailing list. There are also
-informational warnings that you might like to take on board or
-not. Piping the output of \texttt{cmake} through \texttt{less} or
-\texttt{tee} can be useful, too.
+consult the gmx-users mailing list. There are also informational
+warnings that you might like to take on board or not. Piping the
+output of \verb+cmake+ through \verb+less+ or \verb+tee+ can be
+useful, too.
 
 \cmake{} works in an iterative fashion, re-running each time a setting
 is changed to try to make sure other things are consistent. Once
-things seem consistent, the iterations stop. Once \texttt{cmake}
+things seem consistent, the iterations stop. Once \verb+cmake+
 returns, you can see all the settings that were chosen and information
-about them by using 
+about them by using e.g. the curses interface
 \begin{verbatim}
 $ ccmake ..
 \end{verbatim}
+You can actually use \verb+ccmake+ directly in the first step, but then
+most of the status messages will merely blink in the lower part
+of the terminal rather than be written to standard out. Some platforms
+like Windows or Mac even have native graphical user interfaces for
+\cmake{}, and it can create project files for almost any build environment
+you want (including Visual Studio or Xcode).
 Check out \url{http://www.cmake.org/cmake/help/runningcmake.html} for
 general advice on what you are seeing and how to navigate and change
 things. The settings you might normally want to change are already
-presented. If you make any changes, then \texttt{ccmake} will notice
+presented. If you make any changes, then \verb+ccmake+ will notice
 that and require that you re-configure (using '\verb+c+'), so that it
 gets a chance to make changes that depend on yours and perform more
 checking. This might require several configuration stages when you are
-using \texttt{ccmake} - when you are using \texttt{cmake} the
+using \verb+ccmake+ - when you are using \verb+cmake+ the
 iteration is done behind the scenes.
 
 A key thing to consider here is the setting of
-\texttt{GMX\_INSTALL\_PREFIX}. You will need to be able to write to this
-directory in order to install \gromacs{} later, and if you change your
-mind later, changing it in the cache triggers a full re-build,
+\verb+CMAKE_INSTALL_PREFIX+. You will need to be able to write to
+this directory in order to install \gromacs{} later, and if you change
+your mind later, changing it in the cache triggers a full re-build,
 unfortunately. So if you do not have super-user privileges on your
 machine, then you will need to choose a sensible location within your
 home directory for your \gromacs{} installation.
 
-When \texttt{cmake} or \texttt{ccmake} have completed iterating, the
+When \verb+cmake+ or \verb+ccmake+ have completed iterating, the
 cache is stable and a build tree can be generated, with '\verb+g+' in
-\texttt{ccmake} or automatically with \texttt{cmake}.
+\verb+ccmake+ or automatically with \verb+cmake+.
+
+You should not attempt to change compilers after the initial run of
+\cmake{}. If you need to change, clean up and start again.
 
 \subsection{Using CMake command-line options}
 Once you become comfortable with setting and changing options, you
 may know in advance how you will configure GROMACS. If so, you can
-speed things up by invoking \texttt{cmake} with a command like:
+speed things up by invoking \verb+cmake+ with a command like:
 \begin{verbatim}
-$ cmake .. -DGMX_GPU=ON -DGMX_MPI=ON -DGMX_INSTALL_PREFIX=/home/marydoe/programs
+$ cmake .. -DGMX_GPU=ON -DGMX_MPI=ON -DCMAKE_INSTALL_PREFIX=/home/marydoe/programs
 \end{verbatim}
 to build with GPUs, MPI and install in a custom location. You can even
 save that in a shell script to make it even easier next time. You can
-also do this kind of thing with \texttt{ccmake}, but you should avoid
+also do this kind of thing with \verb+ccmake+, but you should avoid
 this, because the options set with '\verb+-D+' will not be able to be
-changed interactively in that run of \texttt{ccmake}.
+changed interactively in that run of \verb+ccmake+.
 
 \subsection{CMake advanced options}
-The options that can be seen with \texttt{ccmake} are ones that we
+The options that can be seen with \verb+ccmake+ are ones that we
 think a reasonable number of users might want to consider
 changing. There are a lot more options available, which you can see by
-toggling the advanced mode in \texttt{ccmake} on and off with
+toggling the advanced mode in \verb+ccmake+ on and off with
 '\verb+t+'. Even there, most of the variables that you might want to
 change have a '\verb+CMAKE_+' or '\verb+GMX_+' prefix.
 
@@ -317,9 +398,9 @@ change have a '\verb+CMAKE_+' or '\verb+GMX_+' prefix.
 If libraries are installed in non-default locations their location can
 be specified using the following environment variables:
 \begin{itemize}
-\item \texttt{CMAKE\_INCLUDE\_PATH} for header files
-\item \texttt{CMAKE\_LIBRARY\_PATH} for libraries
-\item \texttt{CMAKE\_PREFIX\_PATH} for header, libraries and binaries
+\item \verb+CMAKE_INCLUDE_PATH+ for header files
+\item \verb+CMAKE_LIBRARY_PATH+ for libraries
+\item \verb+CMAKE_PREFIX_PATH+ for header, libraries and binaries
   (e.g. '\verb+/usr/local+').
 \end{itemize}
 The respective '\verb+include+', '\verb+lib+', or '\verb+bin+' is
@@ -331,96 +412,88 @@ a '\verb+bash+' shell are used like:
 $ CMAKE_PREFIX_PATH=/opt/fftw:/opt/cuda cmake ..
 \end{verbatim}
 
-The \texttt{CC} and \texttt{CXX} environment variables are also useful
+The \verb+CC+ and \verb+CXX+ environment variables are also useful
 for indicating to \cmake{} which compilers to use, which can be very
 important for maximising \gromacs{} performance. Similarly,
-\texttt{CFLAGS}/\texttt{CXXFLAGS} can be used to pass compiler
+\verb+CFLAGS+/\verb+CXXFLAGS+ can be used to pass compiler
 options, but note that these will be appended to those set by
 \gromacs{} for your build platform and build type. You can customize
-some of this with advanced options such as \texttt{CMAKE\_C\_FLAGS}
+some of this with advanced options such as \verb+CMAKE_C_FLAGS+
 and its relatives.
 
 See also: \url{http://cmake.org/Wiki/CMake_Useful_Variables#Environment_Variables}
 
-\subsection{CMake advice during the GROMACS 4.6 beta phase}
-We'd like users to have the ability to change any setting and still
-have the \cmake{} cache stable; ie. not have things you set
-mysteriously change, or (worse) the whole thing breaks. We're not
-there yet. If you know in advance you will want to use a particular
-setting, set that on the initial \texttt{cmake} command line. If you
-have to change compilers, do that there, or immediately afterwards in
-\texttt{ccmake}. Gross changes like GPU or shared libraries on/off are
-more likely to work if you do them on the initial command line,
-because that's how we've been doing it while developing and
-testing. If you do make a mess of things, there's a great thing about
-an out-of-source build - you can just do '\verb+rm -rf *+' and start
-again. Easy!
-
-We are interested in learning how you managed to break things. If you
-can reproducibly reach a state where \cmake{} can't proceed, or
-subsequent compilation/linking/running fails, then we need to know so
-we can fix it!
-
 \subsection{Native GPU acceleration}
-If you have the \cuda{} SDK installed, you can use \cmake{}
-with:
+If you have the \cuda{} Software Development Kit installed, you can
+use \cmake{} with:
 \begin{verbatim}
 cmake .. -DGMX_GPU=ON -DCUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda
 \end{verbatim}
 (or whichever path has your installation). Note that this will require
 a working C++ compiler, and in some cases you might need to handle
 this manually, e.g. with the advanced option
-\texttt{CUDA\_NVCC\_HOST\_COMPILER}.
+\verb+CUDA_NVCC_HOST_COMPILER+.
 
-More documentation needed here - particular discussion of fiddly
-details on Windows, Linux and Mac required. Not all compilers on all
-systems can be made to work.
+Historically, Linux GPU builds have received most testing, but we 
+want to support GPU builds both under x86 Linux, Windows, Mac OS X and in the
+future ARM. Any feedback on this build process (and fixes in particular) are very
+welcome!
 
 \subsection{Static linking}
-Dynamic linking of the \gromacs{} executables will lead to a smaller
-disk footprint when installed, and so is the default. However, on some
-hardware or under some circumstances you might need to do static
-linking. To link \gromacs{} binaries statically against the internal
-\gromacs{} libraries, set \texttt{BUILD\_SHARED\_LIBS=OFF}. To link
-statically against external libraries as well, the
-\texttt{GMX\_PREFER\_STATIC\_LIBS=ON} option can be used. Note, that
-in general \cmake{} picks up whatever is available, so this option
-only instructs \cmake{} to prefer static libraries when both static
-and shared are available. If no static version of an external library
-is available, even when the aforementioned option is ON, the shared
-library will be used. Also note, that the resulting binaries will
-still be dynamically linked against system libraries if that is all
-that is available.
-
-\subsection{Suffixes for binaries and libraries}
+Dynamic linking of the \gromacs{} executables will lead to a
+smaller disk footprint when installed, and so is the default on
+platforms where we believe it has been tested repeatedly and found to work.
+In general, this includes Linux, Windows, Mac OS X and BSD systems.
+Static binaries take much more space, but on some hardware and/or under
+some conditions they are necessary, most commonly when you are running a parallel
+simulation using MPI libraries. 
+
+\begin{itemize}
+\item To link \gromacs{} binaries
+statically against the internal \gromacs{} libraries, set
+\verb+BUILD_SHARED_LIBS=OFF+.
+\item To link statically against external
+libraries as well, the \verb+GMX_PREFER_STATIC_LIBS=ON+ option can be
+used. Note, that in general \cmake{} picks up whatever is available,
+so this option only instructs \cmake{} to prefer static libraries when
+both static and shared are available. If no static version of an
+external library is available, even when the aforementioned option is
+ON, the shared library will be used. Also note, that the resulting
+binaries will still be dynamically linked against system libraries if
+that is all that is available (common on Mac OS X).
+\end{itemize}
+
+\subsection{Changing the names of GROMACS binaries and libraries}
 It is sometimes convenient to have different versions of the same
 \gromacs{} libraries installed. The most common use cases have been
 single and double precision, and with and without \mpi{}. By default,
 \gromacs{} will suffix binaries and libraries for such builds with
 '\verb+_d+' for double precision and/or '\verb+_mpi+' for \mpi{} (and
 nothing otherwise). This can be controlled manually with
-\texttt{GMX\_DEFAULT\_SUFFIX}, \texttt{GMX\_BINARY\_SUFFIX} and
-\texttt{GMX\_LIBRARY\_SUFFIX}.
+\verb+GMX_DEFAULT_SUFFIX+, \verb+GMX_BINARY_SUFFIX+ and
+\verb+GMX_LIBRARY_SUFFIX+. This can also be useful for resolving
+libary-naming conflicts with existing packges (\verb+GMX_PREFIX_LIBMD+
+also can be useful).
 
 \subsection{Building \gromacs{}}
 
 Once you have a stable cache, you can build \gromacs{}. If you're not
 sure the cache is stable, you can re-run \verb+cmake ..+ or
-\verb+ccmake ..+' to see. Then you can run \texttt{make} to start the
-compilation. Before actual compilation starts, \texttt{make} checks
+\verb+ccmake ..+' to see. Then you can run \verb+make+ to start the
+compilation. Before actual compilation starts, \verb+make+ checks
 that the cache is stable, so if it isn't you will see \cmake{} run
 again.
 
 So long as any changes you've made to the configuration are sensible,
-it is expected that the \texttt{make} procedure will always complete
+it is expected that the \verb+make+ procedure will always complete
 successfully. The tests \gromacs{} makes on the settings you choose
 are pretty extensive, but there are probably a few cases we haven't
-thought of yet. Search the web first for solutions to problems,
-but if you need help, ask on \texttt{gmx-users}, being sure to provide
-as much information as possible about what you did, the system you are
+thought of yet. Search the web first for solutions to problems, but if
+you need help, ask on gmx-users, being sure to provide as much
+information as possible about what you did, the system you are
 building on, and what went wrong.
 
-If you have a multi-core or multi-CPU machine with \texttt{N}
+If you have a multi-core or multi-CPU machine with \verb+N+
 processors, then using
 \begin{verbatim}
 $ make -j N
@@ -429,36 +502,80 @@ will generally speed things up by quite a bit.
 
 \subsection{Installing \gromacs{}}
 
-Finally, \texttt{make install} will install \gromacs{} in the
-directory given in \texttt{GMX\_INSTALL\_PREFIX}. If this is an system
+Finally, \verb+make install+ will install \gromacs{} in the
+directory given in \verb+GMX_INSTALL_PREFIX+. If this is an system
 directory, then you will need permission to write there, and you
-should use super-user privileges only for \texttt{make install} and
+should use super-user privileges only for \verb+make install+ and
 not the whole procedure.
 
 \subsection{Getting access to \gromacs{} after installation}
 
-\gromacs{} installs the script \texttt{GMXRC} in the \texttt{bin}
+\gromacs{} installs the script \verb+GMXRC+ in the \verb+bin+
 subdirectory of the installation directory
-(e.g. \texttt{/usr/local/gromacs/bin/GMXRC}), which you should source
+(e.g. \verb+/usr/local/gromacs/bin/GMXRC+), which you should source
 from your shell:
 \begin{verbatim}
 $ source your-installation-prefix-here/bin/GMXRC
 \end{verbatim}
 
-It will detect what kind of shell you are running and
-set up your environment for using \gromacs{}. You may wish to arrange
-for your login scripts to do this automatically; please search the web
-for instructions on how to do this for your shell.
+It will detect what kind of shell you are running and set up your
+environment for using \gromacs{}. You may wish to arrange for your
+login scripts to do this automatically; please search the web for
+instructions on how to do this for your shell. 
+
+Many of the \gromacs{} programs rely on data installed in our
+\verb+share/gromacs+ directory. By default, the programs will use
+the environment variables set in the GMXRC script, and if this is not
+available they will try to guess the path based on their own location.
+This usually works well unless you change the names of directories
+inside the install tree. If you still need to do that, you might want to recompile
+with the new install location properly set, or edit the \verb+GMXRC+ script.
 
 \subsection{Testing \gromacs{} for correctness}
-TODO install and use regression set
+Since 2011, the \gromacs{} development uses an automated system where
+every new patch is subject to regression testing. While this improves
+reliability quite a lot, not everything is tested, and since we
+increasingly rely on cutting edge compiler features there is
+non-negligible risk that the default compiler on your system could
+have bugs. We have tried our best to test and refuse to use known bad
+versions in \cmake{}, but we strongly recommend that you run through
+the regression tests yourself. It only takes a few minutes, after
+which you can trust your build.
+
+The simplest way to run the checks is to build \gromacs{} with
+\verb+-DREGRESSIONTEST_DOWNLOAD+, and run \verb+make check+.
+\gromacs{} will automatically download and run the tests for you.
+Alternatively, you can download and unpack the tarball yourself from
+\url{http://gerrit.gromacs.org/download/regressiontests-4.6.tar.gz},
+and use the advanced \cmake{} option \verb+REGRESSIONTEST_PATH+ to
+specify the path to the unpacked tarball, which will then be used for
+testing. If this doesn't work, then please read on.
+
+The regression tests are available from the \gromacs{} website and ftp
+site.  Once you have downloaded them, unpack the tarball, source
+\verb+GMXRC+ as described above, and run \verb+./gmxtest.pl all+
+inside the regression tests folder. You can find more options
+(e.g. adding \verb+double+ when using double precision) if you just
+execute the script without options.
+
+Hopefully you will get a report that all tests have passed. If there
+are individual failed tests it could be a sign of a compiler bug, or
+that a tolerance is just a tiny bit too tight. Check the output files
+the script directs you too, and try a different or newer compiler if
+the errors appear to be real. If you cannot get it to pass the
+regression tests, you might try dropping a line to the gmx-users
+mailing list, but then you should include a detailed description of
+your hardware and an example logfile from mdrun (which contains
+valuable information in the header).
 
 \subsection{Testing \gromacs{} for performance}
-TODO benchmarks
+We are still working on a set of benchmark systems for testing
+the performance of \gromacs{}. Until that is ready, we recommend that
+you start by comparing the performance to release 4.5, and also try
+a few different parallelization options.
 
 \subsection{Having difficulty?}
-
-You're not alone, this can be a complex task. If you encounter a
+You're not alone - this can be a complex task! If you encounter a
 problem with installing \gromacs{}, then there are a number of
 locations where you can find assistance. It is recommended that you
 follow these steps to find the solution:
@@ -469,70 +586,122 @@ follow these steps to find the solution:
 \item Search the \gromacs{} website and users emailing list for
   information on the error.
 \item Search the internet using a search engine such as Google.
-\item Post to the \gromacs{} users emailing list \texttt{gmx-users}
-  for assistance. Be sure to give a full description of what you have
-  done and why you think it didn't work. Give details about the system
-  on which you are installing. Copy and paste your command line and as
+\item Post to the \gromacs{} users emailing list gmx-users for
+  assistance. Be sure to give a full description of what you have done
+  and why you think it didn't work. Give details about the system on
+  which you are installing. 
+  Copy and paste your command line and as
   much of the output as you think might be relevant - certainly from
-  the first indication of a problem. Describe the machine and
-  operating system you are running on. People who might volunteer to
+  the first indication of a problem. In particular, please try to include at
+  least the header from the mdrun logfile, and preferably the entire file.
+  People who might volunteer to
   help you do not have time to ask you interactive detailed follow-up
   questions, so you will get an answer faster if you provide as much
-  information as you think could possibly help.
+  information as you think could possibly help. High quality bug reports 
+  tend to receive rapid high quality answers.
 \end{enumerate}
 
 \section{Special instructions for some platforms}
 
 \subsection{Building on Windows}
-
 Building on Cygwin/MinGW/etc. works just like Unix. Please see the
 instructions above.
 
 Building on Windows using native compilers is rather similar to
 building on Unix, so please start by reading the above. Then, download
-and unpack the GROMACS source archive. The UNIX-standard
-\texttt{.tar.gz} format can be managed on Windows, but you may prefer
-to browse \url{ftp://ftp.gromacs.org/pub/gromacs} to obtain a
-\texttt{.zip} format file, which doesn't need any external tools to
-unzip on recent Windows systems. Make a folder in which to do the
-out-of-source build of \gromacs{}. For example, make it within the
-folder unpacked from the source archive, and call it ``build-cmake''.
-
-Next, you need to open a command shell. If you do this from within
+and unpack the GROMACS source archive. The UNIX-standard .tar.gz
+format can be managed on Windows, but you may prefer to browse
+\url{ftp://ftp.gromacs.org/pub/gromacs} to obtain a zip format file,
+which doesn't need any external tools to unzip on recent Windows
+systems. Make a folder in which to do the out-of-source build of
+\gromacs{}. For example, make it within the folder unpacked from the
+source archive, and call it ``build-cmake''. 
+
+For \cmake{}, you can either use the graphical user interface provided
+on Windows, or you can use a command line shell with instructions
+similar to the UNIX ones above. If you open a shell from within
 your IDE (e.g. Microsoft Visual Studio), it will configure the
-environment for you. If you use a normal Windows command shell, then
+environment for you, but you might need to tweak this in order to 
+get either a 32-bit or 64-bit build environment. The latter provides the
+fastest executable. If you use a normal Windows command shell, then
 you will need to either set up the environment to find your compilers
-and libraries yourself, or run the \texttt{vcvarsall.bat} batch script
+and libraries yourself, or run the \verb+vcvarsall.bat+ batch script
 provided by MSVC (just like sourcing a bash script under
-Unix). Presumably Intel's IDE has a similar functionality.
+Unix). 
 
-Within that command shell, change to the folder you created above. Run
-\verb+cmake ..+, where the folder you point \cmake{} towards is the
-folder created by the \gromacs{} installer. Resolve issues as
-above. You will probably make your life easier and faster by using the
-new facility to download and install \fftw{} automatically. After the
-initial run of \verb+cmake+, you may wish to use \verb+cmake+,
-\verb+ccmake+ or the GUI version of \cmake{} until your configuration
-is complete.
+With the graphical user interface you will be asked about what compilers
+to use at the initial configuration stage, and if you use the command line
+they can be set in a similar way as under UNIX.
+You will probably make your life easier and faster by using the
+new facility to download and install \fftw{} automatically. 
 
-To compile \gromacs{}, you then use \verb+cmake --build .+ so the
-right tools get used.
+For the build, you can either load the generated solutions file into
+e.g. Visual Studio, or use the command line with \verb+cmake --build .+ 
+so the right tools get used.
 
 \subsection{Building on Cray}
 
-Probably you need to build static libraries only? Volunteer needed.
+Gromacs builds mostly out of the box on modern Cray machines,
+but you want to use static libraries due to the peculiarities with
+parallel job execution.
 
 \subsection{Building on BlueGene}
 
 \subsubsection{BlueGene/P}
 
-Mark to write later. There is currently no native acceleration on this
-platform, but the default plain C kernels will work.
+There is currently no native acceleration on this platform, but the
+default plain C kernels will work. Toolchain files will be improved in
+\gromacs{} 4.6.1.
 
 \subsubsection{BlueGene/Q}
 
-Mark to write later. There is currently no native acceleration on this
-platform, but the default plain C kernels will work.
+There is currently no native acceleration on this platform, but the
+default plain C kernels will work. We have accelerated kernels in
+progress for this platform, but they are not quite done yet.
+
+Only static linking with XL compilers is supported by \gromacs{}. Dynamic
+linking would be supported by the architecture and \gromacs{}, but has no
+advantages other than disk space, and is generally discouraged on
+BlueGene for performance reasons.
+
+Computation on BlueGene floating-point units is always done in
+double-precision. However, single-precision builds of \gromacs{} are
+still normal and encouraged since they use cache more efficiently. 
+The BlueGene hardware automatically
+converts values stored in single precision in memory to double
+precision in registers for computation, converts the results back to
+single precision correctly, and does so for no additional cost. As
+with other platforms, doing the whole computation in double precision
+normally shows no improvement in accuracy and costs twice as much time
+moving memory around.
+
+You need to arrange for FFTW to be installed correctly, following the
+above instructions.
+
+mpicc is used for compiling and linking. This can make it awkward to
+attempt to use IBM's optimized BLAS/LAPACK called ESSL. Since mdrun is
+the only part of \gromacs{} that should normally run on the compute
+nodes, and there is nearly no need for linear algebra support for
+mdrun, it is recommended to use the \gromacs{} built-in linear algebra
+routines - it is rare for this to be a bottleneck.
+
+\begin{verbatim}
+cmake .. -DCMAKE_TOOLCHAIN_FILE=BlueGeneQ-static-XL-C \
+         -DCMAKE_PREFIX_PATH=/your/fftw/installation/prefix
+make mdrun
+make install-mdrun
+\end{verbatim}
+It is possible to configure and make the remaining \gromacs{} tools
+with the compute node toolchain, but as none of those tools are
+\mpi{}-aware, this would not normally be useful. Instead, these should
+be planned to run on the login node, and a seperate \gromacs{}
+installation performed for that using the login node's toolchain.
+
+\subsubsection{Fujitsu PRIMEHPC}
+
+This is the architecture of the K computer, which uses Fujitsu Sparc64viiifx 
+chips. Gromacs-4.6 will build with default C kernels on this architecture,
+and Gromacs-4.6.1 will add accelerated kernels and a custom toolchain.
 
 \section{Tested platforms}
 
@@ -540,8 +709,15 @@ While it is our best belief that \gromacs{} will build and run pretty
 much everywhere, it's important that we tell you where we really know
 it works because we've tested it. We do test on Linux, Windows, and
 Mac with a range of compilers and libraries for a range of our
-configuration options. Every commit in our \texttt{git} source code
-repository is tested on ... We test irregularly on...
+configuration options. Every commit in our git source code
+repository is currently tested on x86 with gcc versions ranging
+from 4.4 through 4.7, and versions 12 and 13 of the Intel compiler.
+Under Windows we test both the visual studio compilers and icc,
+
+We test irregularly on BlueGene/L, BlueGene/P, BlueGene/Q, Cray, 
+Fujitsu PRIMEHPC, Google nativeclient and other environments. In 
+the future we expect ARM to be an important test target too, but this
+is currently not included.
 
 Contributions to this section are welcome.
 
index a7fb8ec54e0ca427f477554643e43710eee8e69b..bc10a6fe1c471d07d9804d5a40e8f1d727b3e1b9 100644 (file)
@@ -75,7 +75,7 @@ if (${FFTW}_FOUND)
   foreach(AVX_FUNCTION ${${FFTW}_FUNCTION_PREFIX}_have_simd_avx)
     check_library_exists("${${FFTW}_LIBRARIES}" "${AVX_FUNCTION}" "" ${FFTW}_HAVE_${AVX_FUNCTION})
     if(${FFTW}_HAVE_${AVX_FUNCTION})
-      set(${FFTW}_HAVE_AVX TRUE CACHE BOOL "If ${${FFTW}_PKG} was built with AVX support")
+      set(${FFTW}_HAVE_AVX TRUE)
       break()
     endif(${FFTW}_HAVE_${AVX_FUNCTION})
   endforeach()
@@ -84,7 +84,7 @@ if (${FFTW}_FOUND)
   foreach(SIMD_FCT ${${FFTW}_FUNCTION_PREFIX}_have_simd_sse2;${${FFTW}_FUNCTION_PREFIX}_have_simd_avx;${${FFTW}_FUNCTION_PREFIX}_have_simd_altivec;${${FFTW}_FUNCTION_PREFIX}_have_simd_neon;${${FFTW}_FUNCTION_PREFIX}_have_sse2;${${FFTW}_FUNCTION_PREFIX}_have_sse;${${FFTW}_FUNCTION_PREFIX}_have_altivec)
     check_library_exists("${${FFTW}_LIBRARIES}" "${SIMD_FCT}" "" ${FFTW}_HAVE_${SIMD_FCT})
     if(${FFTW}_HAVE_${SIMD_FCT})
-      set(${FFTW}_HAVE_SIMD TRUE CACHE  BOOL "If ${${FFTW}_PKG} was built with SIMD support")
+      set(${FFTW}_HAVE_SIMD TRUE)
       break()
     endif(${FFTW}_HAVE_${SIMD_FCT})
   endforeach()
@@ -98,6 +98,5 @@ if (${FFTW}_FOUND)
   endif ()
   set(CMAKE_REQUIRED_LIBRARIES)
 endif (${FFTW}_FOUND)
-set(${FFTW}_HAVE_SIMD FALSE CACHE BOOL "If ${${FFTW}_PKG} was built with SIMD support")
 
-mark_as_advanced(${FFTW}_INCLUDE_DIR ${FFTW}_LIBRARY ${FFTW}_HAVE_SIMD ${FFTW}_HAVE_AVX)
+mark_as_advanced(${FFTW}_INCLUDE_DIR ${FFTW}_LIBRARY)
diff --git a/cmake/FortranCInterface.cmake b/cmake/FortranCInterface.cmake
deleted file mode 100755 (executable)
index 6551658..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-# FortranCInterface.cmake
-#
-# This file defines the function create_fortran_c_interface.
-# this function is used to create a configured header file 
-# that contains a mapping from C to a Fortran function using
-# the correct name mangling scheme as defined by the current 
-# fortran compiler.  
-#
-# The function tages a list of functions and the name of 
-# a header file to configure.  
-#
-# This file also defines some helper functions that are used
-# to detect the fortran name mangling scheme used by the 
-# current Fortran compiler.
-#  test_fortran_mangling - test a single fortran mangling 
-#  discover_fortran_mangling - loop over all combos of fortran
-#   name mangling and call test_fortran_mangling until one of them
-#   works.
-#  discover_fortran_module_mangling - try different types of 
-#  fortran modle name mangling to find one that works
-#
-#
-#
-# this function tests a single fortran mangling.  
-# CODE - test code to try should define a subroutine called "sub"
-# PREFIX - string to put in front of sub
-# POSTFIX - string to put after sub
-# ISUPPER - if TRUE then sub will be called as SUB
-# DOC - string used in status checking Fortran ${DOC} linkage
-# SUB - the name of the SUB to call
-# RESULT place to store result TRUE if this linkage works, FALSE
-#        if not.
-#
-function(test_fortran_mangling CODE PREFIX ISUPPER POSTFIX DOC SUB RESULT)
-  if(ISUPPER)
-    string(TOUPPER "${SUB}" sub)
-  else(ISUPPER) 
-    string(TOLOWER "${SUB}" sub)
-  endif(ISUPPER)
-  set(FUNCTION "${PREFIX}${sub}${POSTFIX}")
-  # create a fortran file with sub called sub
-  # 
-  set(TMP_DIR
-    "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckFortranLink")
-  file(REMOVE_RECURSE "${TMP_DIR}")
-  file(WRITE "${TMP_DIR}/test.f" "${CODE}"    )
-  message(STATUS "checking Fortran ${DOC} linkage: ${FUNCTION}")
-  file(WRITE "${TMP_DIR}/ctof.c"
-    "
-      extern ${FUNCTION}();
-      int main() { ${FUNCTION}(); return 0;}
-    "
-    )
-  file(WRITE "${TMP_DIR}/CMakeLists.txt"
-    "
-     project(testf C Fortran)
-     add_library(flib test.f)
-     add_executable(ctof ctof.c)
-     target_link_libraries(ctof flib)
-    "
-    )
-  set(FORTRAN_NAME_MANGLE_TEST FALSE)
-  try_compile(FORTRAN_NAME_MANGLE_TEST "${TMP_DIR}" "${TMP_DIR}"
-    testf
-    OUTPUT_VARIABLE output)
-  if(FORTRAN_NAME_MANGLE_TEST)
-    set(${RESULT} TRUE PARENT_SCOPE)
-  else()
-    set(${RESULT} FALSE PARENT_SCOPE)
-  endif()
-endfunction(test_fortran_mangling)
-
-# this function discovers the name mangling scheme used
-# for functions in a fortran module.  
-function(discover_fortran_module_mangling prefix suffix found)
-  set(CODE 
-    "
-      module test_interface
-      interface dummy
-         module procedure sub
-      end interface
-      contains
-        subroutine sub
-        end subroutine
-      end module test_interface
-    ")
-  set(worked FALSE)
-  foreach(interface 
-      "test_interface$" 
-      "TEST_INTERFACE_mp_" 
-      "_test_interface__" 
-      "__test_interface__" 
-      "__test_interface_NMOD_" 
-      "__test_interface_MOD_")
-    test_fortran_mangling("${CODE}" "${interface}"
-      ${FORTRAN_C_MANGLING_UPPERCASE} "" "module" "sub" worked)
-    if(worked)
-      # if this is the upper case module match then
-      # lower case it for the extraction of pre and post strings
-      if("${interface}" MATCHES "TEST_INTERFACE")
-        string(TOLOWER "${interface}" interface)
-      endif()
-      string(REGEX REPLACE "(.*)test_interface(.*)" "\\1" pre "${interface}")
-      string(REGEX REPLACE "(.*)test_interface(.*)" "\\2" post "${interface}")
-      set(${prefix} "${pre}" PARENT_SCOPE)
-      set(${suffix} "${post}" PARENT_SCOPE)
-      set(${found} TRUE PARENT_SCOPE)
-      return()
-    endif(worked)
-  endforeach(interface)
-  if(NOT worked)
-    message(STATUS "Failed to find C binding to Fortran module functions.")
-    set(${prefix} "BROKEN_C_FORTRAN_MODULE_BINDING" PARENT_SCOPE)
-    set(${suffix} "BROKEN_C_FORTRAN_MODULE_BINDING" PARENT_SCOPE)
-    set(${found} FALSE PARENT_SCOPE)
-  endif(NOT worked)
-endfunction(discover_fortran_module_mangling)
-
-
-function(discover_fortran_mangling prefix isupper suffix extra_under_score
-    found )
-  set(CODE 
-    "
-      subroutine sub
-      end subroutine sub
-    ")
-  foreach(post "_" "")
-    foreach(isup FALSE TRUE)
-      foreach(pre "" "_" "__")
-        set(worked FALSE)
-        test_fortran_mangling("${CODE}" "${pre}" ${isup}
-          "${post}" "function" sub worked )
-        if(worked)
-          message(STATUS "found Fortran function linkage")
-          set(${isupper} "${isup}" PARENT_SCOPE)
-          set(${prefix} "${pre}" PARENT_SCOPE)
-          set(${suffix} "${post}" PARENT_SCOPE)
-          set(${found} TRUE PARENT_SCOPE)
-          set(CODE 
-            "
-      subroutine my_sub
-      end subroutine my_sub
-    ")
-          set(worked FALSE)
-          test_fortran_mangling("${CODE}" "${pre}" ${isup}
-            "${post}" "function with _ " my_sub worked )
-          if(worked)
-            set(${extra_under_score} FALSE PARENT_SCOPE)
-          else(worked)
-            test_fortran_mangling("${CODE}" "${pre}" ${isup}
-              "${post}_" "function with _ " my_sub worked )
-            if(worked)
-              set(${extra_under_score} TRUE PARENT_SCOPE)
-            endif(worked)
-          endif(worked)
-        return()
-        endif()
-      endforeach()
-    endforeach()
-  endforeach()
-  set(${found} FALSE PARENT_SCOPE)
-endfunction(discover_fortran_mangling)
-
-function(create_fortran_c_interface NAMESPACE FUNCTIONS HEADER)
-  if(NOT FORTRAN_C_MANGLING_FOUND)
-    # find regular fortran function mangling
-    discover_fortran_mangling(prefix isupper suffix extra_under found)
-    if(NOT found)
-      message(SEND_ERROR "Could not find fortran c name mangling.")
-      return()
-    endif(NOT found)
-    # find fortran module function mangling
-    set(FORTRAN_C_PREFIX "${prefix}" CACHE INTERNAL
-      "PREFIX for Fortran to c name mangling")
-    set(FORTRAN_C_SUFFIX "${suffix}" CACHE INTERNAL
-      "SUFFIX for Fortran to c name mangling")
-    set(FORTRAN_C_MANGLING_UPPERCASE ${isupper} CACHE INTERNAL 
-      "Was fortran to c mangling found" )
-    set(FORTRAN_C_MANGLING_EXTRA_UNDERSCORE ${extra_under} CACHE INTERNAL 
-      "If a function has a _ in the name does the compiler append an extra _" )
-    set(FORTRAN_C_MANGLING_FOUND TRUE CACHE INTERNAL 
-      "Was fortran to c mangling found" )
-    set(prefix )
-    set(suffix )
-    set(found FALSE)
-    # only try this if the compiler is F90 compatible
-    if(CMAKE_Fortran_COMPILER_SUPPORTS_F90)
-      discover_fortran_module_mangling(prefix suffix found)
-    endif(CMAKE_Fortran_COMPILER_SUPPORTS_F90)
-    if(found)
-      message(STATUS "found Fortran module linkage")
-    else(found)
-      message(STATUS "Failed to find Fortran module linkage")
-    endif(found)
-    set(FORTRAN_C_MODULE_PREFIX "${prefix}" CACHE INTERNAL
-      "PREFIX for Fortran to c name mangling")
-    set(FORTRAN_C_MODULE_SUFFIX "${suffix}" CACHE INTERNAL
-      "SUFFIX for Fortran to c name mangling")
-    set(FORTRAN_C_MODULE_MANGLING_FOUND ${found} CACHE INTERNAL
-      "Was for Fortran to c name mangling found for modules")
-  endif(NOT FORTRAN_C_MANGLING_FOUND)
-  foreach(f ${${FUNCTIONS}})
-    if(FORTRAN_C_MANGLING_UPPERCASE)
-      string(TOUPPER "${f}" fcase)
-    else()
-      string(TOLOWER "${f}" fcase)
-    endif()
-    if("${f}" MATCHES ":")
-      string(REGEX REPLACE "(.*):(.*)" "\\1" module "${f}")
-      string(REGEX REPLACE "(.*):(.*)" "\\2" function "${f}")
-      string(REGEX REPLACE "(.*):(.*)" "\\1" module_case "${fcase}")
-      string(REGEX REPLACE "(.*):(.*)" "\\2" function_case "${fcase}")
-      set(HEADER_CONTENT "${HEADER_CONTENT}
-#define ${NAMESPACE}${module}_${function} ${FORTRAN_C_MODULE_PREFIX}${module_case}${FORTRAN_C_MODULE_SUFFIX}${function_case}
-")
-    else("${f}" MATCHES ":")
-      set(function "${FORTRAN_C_PREFIX}${fcase}${FORTRAN_C_SUFFIX}")
-      if("${f}" MATCHES "_" AND FORTRAN_C_MANGLING_EXTRA_UNDERSCORE)
-        set(function "${function}_")
-      endif("${f}" MATCHES "_" AND FORTRAN_C_MANGLING_EXTRA_UNDERSCORE)
-      set(HEADER_CONTENT "${HEADER_CONTENT}
-#define ${NAMESPACE}${f} ${function}
-")
-    endif("${f}" MATCHES ":")
-  endforeach(f)
-  configure_file(
-    "${CMAKE_ROOT}/Modules/FortranCInterface.h.in"
-    ${HEADER} @ONLY)
-  message(STATUS "created ${HEADER}")
-endfunction()
-
index 3809d02e957f946827a1444b9881d9c6f340fa57..45c3ea5301bcc085cc37926b242fc2b89c69a850 100644 (file)
@@ -66,8 +66,6 @@ MACRO(gmx_c_flags)
             GMX_TEST_CFLAG(CFLAGS_WARN "-Wall" GMXC_CFLAGS)
             GMX_TEST_CFLAG(CFLAGS_STDGNU "-std=gnu99" GMXC_CFLAGS)
             GMX_TEST_CFLAG(CFLAGS_OPT "-ip -funroll-all-loops" GMXC_CFLAGS_RELEASE)
-            GMX_TEST_CFLAG(CFLAGS_X86 "-mtune=core2" GMXC_CFLAGS_RELEASE)
-            GMX_TEST_CFLAG(CFLAGS_IA64 "-mtune=itanium2" GMXC_CFLAGS_RELEASE)
         else()
             GMX_TEST_CFLAG(CFLAGS_WARN "/W2" GMXC_CFLAGS)
             GMX_TEST_CFLAG(CFLAGS_X86 "/Qip" GMXC_CFLAGS_RELEASE)
@@ -81,9 +79,6 @@ MACRO(gmx_c_flags)
             endif()
             GMX_TEST_CXXFLAG(CXXFLAGS_WARN "-Wall" GMXC_CXXFLAGS)
             GMX_TEST_CXXFLAG(CXXFLAGS_OPT "-ip -funroll-all-loops" GMXC_CXXFLAGS_RELEASE)
-            GMX_TEST_CXXFLAG(CXXFLAGS_X86 "-mtune=core2" GMXC_CXXFLAGS_RELEASE)
-            GMX_TEST_CXXFLAG(CXXFLAGS_IA64 "-mtune=itanium2" 
-                              GMXC_CXXFLAGS_RELEASE)
         else()
             GMX_TEST_CXXFLAG(CXXFLAGS_WARN "/W2" GMXC_CXXFLAGS)
             GMX_TEST_CXXFLAG(CXXFLAGS_X86 "/Qip" GMXC_CXXFLAGS_RELEASE)
index d70020a9aa7379ec4c0f3d4b845a6369cdb328c7..d7f88cc02528f9a39c4b8d4e798b9e28425ae6ac 100644 (file)
@@ -1,36 +1,50 @@
 # This macro attempts to parse the version string of the C compiler in use.
-# Currently supported are only compilers that accept "-dumpversion" argument:
-# gcc, Intel Compiler (on Linux and Mac OS), Open64, EkoPath.
+# With CMake 2.8.9 CMake provides a CMAKE_[C|CXX]_COMPILER_VERSION variable
+# so we will use that if available.
+#
+# Currently supported are:
+# - with cmake >2.8.8 all compilers supported by CMake
+# - with cmake <=2.8.8: compilers that accept "-dumpversion" argument:
+#   gcc, Intel Compiler (on Linux and Mac OS), Open64, EkoPath, clang
+#   (and probably other gcc-compatible compilers).
 #
 # C_COMPILER_VERSION    - version string of the current C compiler (CMAKE_C_COMPILER)
 # CXX_COMPILER_VERSION  - version string of the current C++ compiler (CMAKE_CXX_COMPILER)
 #
 macro(get_compiler_version)
     if(NOT C_COMPILER_VERSION)
-        execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
-            RESULT_VARIABLE _cc_dumpversion_res
-            OUTPUT_VARIABLE _cc_dumpversion_out
-           ERROR_VARIABLE  _cc_dumpversion_err
-            OUTPUT_STRIP_TRAILING_WHITESPACE)
+        set(_cc_dumpversion_res 0)
+        if (DEFINED xCMAKE_C_COMPILER_VERSION AND CMAKE_VERSION VERSION_GREATER 2.8.8)
+            set(_cc_version ${CMAKE_C_COMPILER_VERSION})
+        else()
+            execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
+                RESULT_VARIABLE _cc_dumpversion_res
+                OUTPUT_VARIABLE _cc_version
+                OUTPUT_STRIP_TRAILING_WHITESPACE)
+        endif()
 
         if (${_cc_dumpversion_res} EQUAL 0)
-            SET(C_COMPILER_VERSION ${_cc_dumpversion_out}
-                CACHE STRING "C compiler version string" FORCE)
+            SET(C_COMPILER_VERSION ${_cc_version}
+                CACHE STRING "C compiler version" FORCE)
         else ()
             SET(C_COMPILER_VERSION ""
-                CACHE STRING "C compiler version string not available" FORCE)
+                CACHE STRING "C compiler version not available" FORCE)
         endif ()
     endif()
 
     if(NOT CXX_COMPILER_VERSION AND CMAKE_CXX_COMPILER_LOADED)
-        execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion
-            RESULT_VARIABLE _cxx_dumpversion_res
-            OUTPUT_VARIABLE _cxx_dumpversion_out
-           ERROR_VARIABLE  _cxx_dumpversion_err
-            OUTPUT_STRIP_TRAILING_WHITESPACE)
+        set(_cxx_dumpversion_res 0)
+        if (DEFINED CMAKE_CXX_COMPILER_VERSION AND CMAKE_VERSION VERSION_GREATER 2.8.8)
+            set(_cxx_version ${CMAKE_CXX_COMPILER_VERSION})
+        else()
+            execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion
+                RESULT_VARIABLE _cxx_dumpversion_res
+                OUTPUT_VARIABLE _cxx_version
+                OUTPUT_STRIP_TRAILING_WHITESPACE)
+        endif()
 
         if (${_cxx_dumpversion_res} EQUAL 0)
-            SET(CXX_COMPILER_VERSION ${_cxx_dumpversion_out}
+            SET(CXX_COMPILER_VERSION ${_cxx_version}
                 CACHE STRING "C++ compiler version string" FORCE)
         else ()
             SET(CXX_COMPILER_VERSION ""
@@ -39,7 +53,7 @@ macro(get_compiler_version)
     endif ()
 
     if (NOT "${C_COMPILER_VERSION}" STREQUAL "${CXX_COMPILER_VERSION}" AND CMAKE_CXX_COMPILER_LOADED)
-        message(WARNING "The version string of the C and C++ compilers does not match!")
+        message(WARNING "The version of the C and C++ compilers does not match. Note that mixing different C/C++ compilers can cause problems!")
     endif ()
 
     mark_as_advanced(C_COMPILER_VERSION CXX_COMPILER_VERSION)
index 8b7c761a2f61451d95b44f58aa11cabb46b151ed..d81ff741104e024f6e3266bedfbc661e25df2871 100644 (file)
@@ -43,8 +43,8 @@ endif()
 # - OFF, TRUE : Will keep GMX_GPU=OFF if no CUDA is detected, but will assemble
 #               a warning message which will be issued at the end of the
 #               configuration if GPU(s) were found in the build system.
-# - ON , FALSE: The user requested GPU builds, will require CUDA and will fail
-#               if it is not available.
+# - ON , FALSE: The user requested GPU build and this requires CUDA, so we will
+#               fail if it is not available.
 # - ON , TRUE : Can't happen (GMX_GPU=ON can only be user-set at this point)
 if((GMX_GPU OR GMX_GPU_AUTO) AND NOT GMX_GPU_DETECTION_DONE)
     if (EXISTS ${CUDA_TOOLKIT_ROOT_DIR})
@@ -77,9 +77,9 @@ if((GMX_GPU OR GMX_GPU_AUTO) AND NOT GMX_GPU_DETECTION_DONE)
 
         set(CUDA_NOTFOUND_MESSAGE "
     mdrun supports native GPU acceleration on NVIDIA hardware with compute
-    capability >=2.0. This requires the NVIDIA CUDA library, which was not
-    found; the location can be hinted by setting CUDA_TOOLKIT_ROOT_DIR as
-    a CMake option (It does not work as an environment variable).
+    capability >=2.0 (Fermi or later). This requires the NVIDIA CUDA toolkit,
+    which was not found. Its location can be hinted by setting the
+    CUDA_TOOLKIT_ROOT_DIR CMake option (does not work as an environment variable).
     The typical location would be /usr/local/cuda[-version].
     Note that CPU or GPU acceleration can be selected at runtime!
 
@@ -89,7 +89,7 @@ if((GMX_GPU OR GMX_GPU_AUTO) AND NOT GMX_GPU_DETECTION_DONE)
     if (NOT CUDA_FOUND)
         if (GMX_GPU_AUTO)
             # Disable GPU acceleration in auto mode
-            message(STATUS "Disabling native GPU acceleration")
+            message(STATUS "No compatible CUDA toolkit found (v3.2+), disabling native GPU acceleration")
             set_property(CACHE GMX_GPU PROPERTY VALUE OFF)
             set(CUDA_NOTFOUND_AUTO ON)
         else ()
@@ -127,7 +127,7 @@ macro(gmx_gpu_setup)
     if(NOT GMX_OPENMP)
         message(WARNING "
     To use GPU acceleration efficiently, mdrun requires OpenMP multi-threading.
-    With no OpenMP a single CPU core can be used with a GPU which is not optimal.
+    Without OpenMP a single CPU core can be used with a GPU which is not optimal.
     Note that with MPI multiple processes can be forced to use a single GPU, but this
     typically inefficient. Note that you need to set both C and C++ compilers that
     support OpenMP (CC and CXX environment variables, respectively) when using GPUs.")
index dce133137a24f92005c56fdc4ffae2dac8568218..ac5d6b5e5452e2db2f8b632b1070f99acd20251b 100644 (file)
@@ -2,7 +2,7 @@ shopt -s extglob
 _do_dssp_compl() {
 local p c
 COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
-if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -s -n -ssdump -map -o -sc -a -ta -aa -h -version -nice -b -e -dt -tu -w -xvg -sss' -- $c)); return 0; fi
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -s -n -ssdump -map -o -sc -a -ta -aa -h -version -nice -b -e -dt -tu -w -xvg -sss -ver' -- $c)); return 0; fi
 case "$p" in
 -tu) COMPREPLY=( $(compgen -W ' fs ps ns us ms s ' -- $c ));;
 -xvg) COMPREPLY=( $(compgen -W ' xmgrace xmgr none ' -- $c ));;
@@ -22,7 +22,7 @@ shopt -s extglob
 _editconf_compl() {
 local p c
 COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
-if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -n -o -mead -bf -h -version -nice -w -ndef -bt -box -angles -d -c -center -aligncenter -align -translate -rotate -princ -scale -density -pbc -grasp -rvdw -sig56 -vdwread -atom -legend -label -conect' -- $c)); return 0; fi
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -n -o -mead -bf -h -version -nice -w -ndef -bt -box -angles -d -c -center -aligncenter -align -translate -rotate -princ -scale -density -pbc -resnr -grasp -rvdw -sig56 -vdwread -atom -legend -label -conect' -- $c)); return 0; fi
 case "$p" in
 -bt) COMPREPLY=( $(compgen -W ' triclinic cubic dodecahedron octahedron ' -- $c ));;
 -f) COMPREPLY=( $(compgen -X '!*.+(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
@@ -36,7 +36,7 @@ shopt -s extglob
 _eneconv_compl() {
 local p c
 COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
-if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -o -h -version -nice -b -e -dt -offset -settime -nosort -scalefac -noerror' -- $c)); return 0; fi
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -o -h -version -nice -b -e -dt -offset -settime -nosort -rmdh -scalefac -noerror' -- $c)); return 0; fi
 case "$p" in
 -f) COMPREPLY=( $(compgen -X '!*.edr*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -o) COMPREPLY=( $(compgen -X '!*.edr*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
@@ -91,7 +91,7 @@ case "$p" in
 -xvg) COMPREPLY=( $(compgen -W ' xmgrace xmgr none ' -- $c ));;
 -errbar) COMPREPLY=( $(compgen -W ' none stddev error 90 ' -- $c ));;
 -P) COMPREPLY=( $(compgen -W ' 0 1 2 3 ' -- $c ));;
--fitfn) COMPREPLY=( $(compgen -W ' none exp aexp exp_exp vac exp5 exp7 exp9 ' -- $c ));;
+-fitfn) COMPREPLY=( $(compgen -W ' none exp aexp exp_exp vac exp5 exp7 exp9 erffit ' -- $c ));;
 -f) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -ac) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -msd) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
@@ -112,7 +112,7 @@ case "$p" in
 -xvg) COMPREPLY=( $(compgen -W ' xmgrace xmgr none ' -- $c ));;
 -type) COMPREPLY=( $(compgen -W ' angle dihedral improper ryckaert-bellemans ' -- $c ));;
 -P) COMPREPLY=( $(compgen -W ' 0 1 2 3 ' -- $c ));;
--fitfn) COMPREPLY=( $(compgen -W ' none exp aexp exp_exp vac exp5 exp7 exp9 ' -- $c ));;
+-fitfn) COMPREPLY=( $(compgen -W ' none exp aexp exp_exp vac exp5 exp7 exp9 erffit ' -- $c ));;
 -f) COMPREPLY=( $(compgen -X '!*.+(xtc|trr|cpt|trj|gro|g96|pdb|g87)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -n) COMPREPLY=( $(compgen -X '!*.ndx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -od) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
@@ -128,14 +128,14 @@ shopt -s extglob
 _g_bar_compl() {
 local p c
 COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
-if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -o -oi -oh -g -h -version -nice -w -xvg -b -e -temp -prec -nbmin -nbmax -nbin' -- $c)); return 0; fi
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -g -o -oi -oh -h -version -nice -w -xvg -b -e -temp -prec -nbmin -nbmax -nbin -extp' -- $c)); return 0; fi
 case "$p" in
 -xvg) COMPREPLY=( $(compgen -W ' xmgrace xmgr none ' -- $c ));;
 -f) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-g) COMPREPLY=( $(compgen -X '!*.edr*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -o) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -oi) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -oh) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--g) COMPREPLY=( $(compgen -X '!*.edr*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 esac }
 complete -F _g_bar_compl g_bar
 shopt -s extglob
@@ -185,7 +185,7 @@ case "$p" in
 -xvg) COMPREPLY=( $(compgen -W ' xmgrace xmgr none ' -- $c ));;
 -maxchi) COMPREPLY=( $(compgen -W ' 0 1 2 3 4 5 6 ' -- $c ));;
 -P) COMPREPLY=( $(compgen -W ' 0 1 2 3 ' -- $c ));;
--fitfn) COMPREPLY=( $(compgen -W ' none exp aexp exp_exp vac exp5 exp7 exp9 ' -- $c ));;
+-fitfn) COMPREPLY=( $(compgen -W ' none exp aexp exp_exp vac exp5 exp7 exp9 erffit ' -- $c ));;
 -s) COMPREPLY=( $(compgen -X '!*.+(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -f) COMPREPLY=( $(compgen -X '!*.+(xtc|trr|cpt|trj|gro|g96|pdb|g87)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -o) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
@@ -204,7 +204,7 @@ shopt -s extglob
 _g_cluster_compl() {
 local p c
 COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
-if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -s -n -dm -o -g -dist -ev -sz -tr -ntr -clid -cl -h -version -nice -b -e -dt -tu -w -xvg -dista -nlevels -cutoff -nofit -max -skip -av -wcl -nst -rmsmin -method -minstruct -binary -M -P -seed -niter -kT' -- $c)); return 0; fi
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -s -n -dm -o -g -dist -ev -sz -tr -ntr -clid -cl -h -version -nice -b -e -dt -tu -w -xvg -dista -nlevels -cutoff -nofit -max -skip -av -wcl -nst -rmsmin -method -minstruct -binary -M -P -seed -niter -kT -nopbc' -- $c)); return 0; fi
 case "$p" in
 -tu) COMPREPLY=( $(compgen -W ' fs ps ns us ms s ' -- $c ));;
 -xvg) COMPREPLY=( $(compgen -W ' xmgrace xmgr none ' -- $c ));;
@@ -328,13 +328,29 @@ case "$p" in
 esac }
 complete -F _g_densmap_compl g_densmap
 shopt -s extglob
+_g_densorder_compl() {
+local p c
+COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -s -f -n -o -or -og -Spect -h -version -nice -b -e -dt -w -1d -bw -bwn -order -axis -method -d1 -d2 -tblock -nlevel' -- $c)); return 0; fi
+case "$p" in
+-method) COMPREPLY=( $(compgen -W ' bisect functional ' -- $c ));;
+-s) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-f) COMPREPLY=( $(compgen -X '!*.+(xtc|trr|cpt|trj|gro|g96|pdb|g87)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-n) COMPREPLY=( $(compgen -X '!*.ndx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-o) COMPREPLY=( $(compgen -X '!*.dat*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-or) COMPREPLY=( $(compgen -X '!*.out*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-og) COMPREPLY=( $(compgen -X '!*.xpm*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-Spect) COMPREPLY=( $(compgen -X '!*.out*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+esac }
+complete -F _g_densorder_compl g_densorder
+shopt -s extglob
 _g_dielectric_compl() {
 local p c
 COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
 if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -d -o -c -h -version -nice -b -e -dt -w -xvg -fft -nox1 -eint -bfit -efit -tail -A -tau1 -tau2 -eps0 -epsRF -fix -ffn -nsmooth' -- $c)); return 0; fi
 case "$p" in
 -xvg) COMPREPLY=( $(compgen -W ' xmgrace xmgr none ' -- $c ));;
--ffn) COMPREPLY=( $(compgen -W ' none exp aexp exp_exp vac exp5 exp7 exp9 ' -- $c ));;
+-ffn) COMPREPLY=( $(compgen -W ' none exp aexp exp_exp vac exp5 exp7 exp9 erffit ' -- $c ));;
 -f) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -d) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -o) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
@@ -342,17 +358,6 @@ case "$p" in
 esac }
 complete -F _g_dielectric_compl g_dielectric
 shopt -s extglob
-_g_dih_compl() {
-local p c
-COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
-if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -s -o -h -version -nice -b -e -dt -w -sa -mult' -- $c)); return 0; fi
-case "$p" in
--f) COMPREPLY=( $(compgen -X '!*.+(xtc|trr|cpt|trj|gro|g96|pdb|g87)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--s) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--o) COMPREPLY=( $(compgen -X '!*.out*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
-esac }
-complete -F _g_dih_compl g_dih
-shopt -s extglob
 _g_dipoles_compl() {
 local p c
 COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
@@ -361,7 +366,7 @@ case "$p" in
 -xvg) COMPREPLY=( $(compgen -W ' xmgrace xmgr none ' -- $c ));;
 -corr) COMPREPLY=( $(compgen -W ' none mol molsep total ' -- $c ));;
 -P) COMPREPLY=( $(compgen -W ' 0 1 2 3 ' -- $c ));;
--fitfn) COMPREPLY=( $(compgen -W ' none exp aexp exp_exp vac exp5 exp7 exp9 ' -- $c ));;
+-fitfn) COMPREPLY=( $(compgen -W ' none exp aexp exp_exp vac exp5 exp7 exp9 erffit ' -- $c ));;
 -en) COMPREPLY=( $(compgen -X '!*.edr*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -f) COMPREPLY=( $(compgen -X '!*.+(xtc|trr|cpt|trj|gro|g96|pdb|g87)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -s) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
@@ -405,7 +410,7 @@ shopt -s extglob
 _g_dist_compl() {
 local p c
 COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
-if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -s -n -o -lt -h -version -nice -b -e -dt -xvg -dist' -- $c)); return 0; fi
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -s -n -o -lt -h -version -nice -b -e -dt -xvg -intra -dist' -- $c)); return 0; fi
 case "$p" in
 -xvg) COMPREPLY=( $(compgen -W ' xmgrace xmgr none ' -- $c ));;
 -f) COMPREPLY=( $(compgen -X '!*.+(xtc|trr|cpt|trj|gro|g96|pdb|g87)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
@@ -416,6 +421,41 @@ case "$p" in
 esac }
 complete -F _g_dist_compl g_dist
 shopt -s extglob
+_g_dos_compl() {
+local p c
+COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -s -n -vacf -mvacf -dos -g -h -version -nice -b -e -dt -w -xvg -nov -recip -abs -normdos -T -acflen -nonormalize -P -fitfn -ncskip -beginfit -endfit' -- $c)); return 0; fi
+case "$p" in
+-xvg) COMPREPLY=( $(compgen -W ' xmgrace xmgr none ' -- $c ));;
+-P) COMPREPLY=( $(compgen -W ' 0 1 2 3 ' -- $c ));;
+-fitfn) COMPREPLY=( $(compgen -W ' none exp aexp exp_exp vac exp5 exp7 exp9 erffit ' -- $c ));;
+-f) COMPREPLY=( $(compgen -X '!*.+(trr|cpt|trj)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-s) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-n) COMPREPLY=( $(compgen -X '!*.ndx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-vacf) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-mvacf) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-dos) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-g) COMPREPLY=( $(compgen -X '!*.log*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+esac }
+complete -F _g_dos_compl g_dos
+shopt -s extglob
+_g_dyecoupl_compl() {
+local p c
+COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -n -ot -oe -o -rhist -khist -h -version -nice -b -e -tu -w -xvg -pbcdist -norm -bins -R0' -- $c)); return 0; fi
+case "$p" in
+-tu) COMPREPLY=( $(compgen -W ' fs ps ns us ms s ' -- $c ));;
+-xvg) COMPREPLY=( $(compgen -W ' xmgrace xmgr none ' -- $c ));;
+-f) COMPREPLY=( $(compgen -X '!*.+(xtc|trr|cpt|trj|gro|g96|pdb|g87)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-n) COMPREPLY=( $(compgen -X '!*.ndx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-ot) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-oe) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-o) COMPREPLY=( $(compgen -X '!*.dat*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-rhist) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-khist) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+esac }
+complete -F _g_dyecoupl_compl g_dyecoupl
+shopt -s extglob
 _g_dyndom_compl() {
 local p c
 COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
@@ -427,10 +467,34 @@ case "$p" in
 esac }
 complete -F _g_dyndom_compl g_dyndom
 shopt -s extglob
+_genbox_compl() {
+local p c
+COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -cp -cs -ci -o -p -h -version -nice -box -nmol -try -seed -vdwd -shell -maxsol -vel' -- $c)); return 0; fi
+case "$p" in
+-cp) COMPREPLY=( $(compgen -X '!*.+(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-cs) COMPREPLY=( $(compgen -X '!*.+(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-ci) COMPREPLY=( $(compgen -X '!*.+(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-o) COMPREPLY=( $(compgen -X '!*.+(gro|g96|pdb|brk|ent|esp|xyz)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-p) COMPREPLY=( $(compgen -X '!*.top*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+esac }
+complete -F _genbox_compl genbox
+shopt -s extglob
+_genconf_compl() {
+local p c
+COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -o -trj -h -version -nice -nbox -dist -seed -rot -shuffle -sort -block -nmolat -maxrot -norenumber' -- $c)); return 0; fi
+case "$p" in
+-f) COMPREPLY=( $(compgen -X '!*.+(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-o) COMPREPLY=( $(compgen -X '!*.+(gro|g96|pdb|brk|ent|esp|xyz)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-trj) COMPREPLY=( $(compgen -X '!*.+(xtc|trr|cpt|trj|gro|g96|pdb|g87)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+esac }
+complete -F _genconf_compl genconf
+shopt -s extglob
 _g_enemat_compl() {
 local p c
 COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
-if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -groups -eref -emat -etot -h -version -nice -b -e -dt -w -xvg -sum -skip -nomean -nlevels -max -min -nocoul -coulr -coul14 -nolj -lj -lj14 -bhamsr -bhamlr -nofree -temp' -- $c)); return 0; fi
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -groups -eref -emat -etot -h -version -nice -b -e -dt -w -xvg -sum -skip -nomean -nlevels -max -min -nocoulsr -coullr -coul14 -noljsr -ljlr -lj14 -bhamsr -bhamlr -nofree -temp' -- $c)); return 0; fi
 case "$p" in
 -xvg) COMPREPLY=( $(compgen -W ' xmgrace xmgr none ' -- $c ));;
 -f) COMPREPLY=( $(compgen -X '!*.edr*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
@@ -444,11 +508,11 @@ shopt -s extglob
 _g_energy_compl() {
 local p c
 COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
-if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -f2 -s -o -viol -pairs -ora -ort -oda -odr -odt -oten -corr -vis -ravg -h -version -nice -b -e -w -xvg -fee -fetemp -zero -sum -dp -nbmin -nbmax -mutot -skip -aver -nmol -nconstr -fluc -orinst -ovec -acflen -nonormalize -P -fitfn -ncskip -beginfit -endfit' -- $c)); return 0; fi
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -f2 -s -o -viol -pairs -ora -ort -oda -odr -odt -oten -corr -vis -ravg -odh -h -version -nice -b -e -w -xvg -fee -fetemp -zero -sum -dp -nbmin -nbmax -mutot -skip -aver -nmol -fluct_props -driftcorr -fluc -orinst -ovec -acflen -nonormalize -P -fitfn -ncskip -beginfit -endfit' -- $c)); return 0; fi
 case "$p" in
 -xvg) COMPREPLY=( $(compgen -W ' xmgrace xmgr none ' -- $c ));;
 -P) COMPREPLY=( $(compgen -W ' 0 1 2 3 ' -- $c ));;
--fitfn) COMPREPLY=( $(compgen -W ' none exp aexp exp_exp vac exp5 exp7 exp9 ' -- $c ));;
+-fitfn) COMPREPLY=( $(compgen -W ' none exp aexp exp_exp vac exp5 exp7 exp9 erffit ' -- $c ));;
 -f) COMPREPLY=( $(compgen -X '!*.edr*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -f2) COMPREPLY=( $(compgen -X '!*.edr*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -s) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
@@ -464,9 +528,38 @@ case "$p" in
 -corr) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -vis) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -ravg) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-odh) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 esac }
 complete -F _g_energy_compl g_energy
 shopt -s extglob
+_genion_compl() {
+local p c
+COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -s -table -n -o -g -pot -p -h -version -nice -xvg -np -pname -pq -nn -nname -nq -rmin -norandom -seed -scale -conc -neutral' -- $c)); return 0; fi
+case "$p" in
+-xvg) COMPREPLY=( $(compgen -W ' xmgrace xmgr none ' -- $c ));;
+-s) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-table) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-n) COMPREPLY=( $(compgen -X '!*.ndx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-o) COMPREPLY=( $(compgen -X '!*.+(gro|g96|pdb|brk|ent|esp|xyz)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-g) COMPREPLY=( $(compgen -X '!*.log*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-pot) COMPREPLY=( $(compgen -X '!*.pdb*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-p) COMPREPLY=( $(compgen -X '!*.top*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+esac }
+complete -F _genion_compl genion
+shopt -s extglob
+_genrestr_compl() {
+local p c
+COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -n -o -of -h -version -nice -fc -freeze -disre -disre_dist -disre_frac -disre_up2 -cutoff -constr' -- $c)); return 0; fi
+case "$p" in
+-f) COMPREPLY=( $(compgen -X '!*.+(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-n) COMPREPLY=( $(compgen -X '!*.ndx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-o) COMPREPLY=( $(compgen -X '!*.itp*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-of) COMPREPLY=( $(compgen -X '!*.ndx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+esac }
+complete -F _genrestr_compl genrestr
+shopt -s extglob
 _g_filter_compl() {
 local p c
 COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
@@ -487,7 +580,7 @@ if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f
 case "$p" in
 -xvg) COMPREPLY=( $(compgen -W ' xmgrace xmgr none ' -- $c ));;
 -P) COMPREPLY=( $(compgen -W ' 0 1 2 3 ' -- $c ));;
--fitfn) COMPREPLY=( $(compgen -W ' none exp aexp exp_exp vac exp5 exp7 exp9 ' -- $c ));;
+-fitfn) COMPREPLY=( $(compgen -W ' none exp aexp exp_exp vac exp5 exp7 exp9 erffit ' -- $c ));;
 -f) COMPREPLY=( $(compgen -X '!*.+(xtc|trr|cpt|trj|gro|g96|pdb|g87)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -s) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa|gro|g96|pdb|brk|ent)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -n) COMPREPLY=( $(compgen -X '!*.ndx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
@@ -513,12 +606,13 @@ shopt -s extglob
 _g_hbond_compl() {
 local p c
 COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
-if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -s -n -num -g -ac -dist -ang -hx -hbn -hbm -don -dan -life -nhbdist -h -version -nice -b -e -dt -xvg -a -r -noda -r2 -abin -rbin -nonitacc -contact -shell -fitstart -fitstart -temp -smooth -dump -max_hb -nomerge -geminate -diff -acflen -nonormalize -P -fitfn -ncskip -beginfit -endfit' -- $c)); return 0; fi
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -s -n -num -g -ac -dist -ang -hx -hbn -hbm -don -dan -life -nhbdist -h -version -nice -b -e -dt -tu -xvg -a -r -noda -r2 -abin -rbin -nonitacc -contact -shell -fitstart -fitstart -temp -smooth -dump -max_hb -nomerge -geminate -diff -acflen -nonormalize -P -fitfn -ncskip -beginfit -endfit' -- $c)); return 0; fi
 case "$p" in
+-tu) COMPREPLY=( $(compgen -W ' fs ps ns us ms s ' -- $c ));;
 -xvg) COMPREPLY=( $(compgen -W ' xmgrace xmgr none ' -- $c ));;
 -geminate) COMPREPLY=( $(compgen -W ' none dd ad aa a4 ' -- $c ));;
 -P) COMPREPLY=( $(compgen -W ' 0 1 2 3 ' -- $c ));;
--fitfn) COMPREPLY=( $(compgen -W ' none exp aexp exp_exp vac exp5 exp7 exp9 ' -- $c ));;
+-fitfn) COMPREPLY=( $(compgen -W ' none exp aexp exp_exp vac exp5 exp7 exp9 erffit ' -- $c ));;
 -f) COMPREPLY=( $(compgen -X '!*.+(xtc|trr|cpt|trj|gro|g96|pdb|g87)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -s) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -n) COMPREPLY=( $(compgen -X '!*.ndx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
@@ -572,6 +666,40 @@ case "$p" in
 esac }
 complete -F _g_helixorient_compl g_helixorient
 shopt -s extglob
+_g_hydorder_compl() {
+local p c
+COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -n -s -o -or -Spect -h -version -nice -b -e -dt -w -d -bw -sgang1 -sgang2 -tblock -nlevel' -- $c)); return 0; fi
+case "$p" in
+-d) COMPREPLY=( $(compgen -W ' z x y ' -- $c ));;
+-f) COMPREPLY=( $(compgen -X '!*.+(xtc|trr|cpt|trj|gro|g96|pdb|g87)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-n) COMPREPLY=( $(compgen -X '!*.ndx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-s) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-o) COMPREPLY=( $(compgen -X '!*.xpm*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-or) COMPREPLY=( $(compgen -X '!*.out*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-Spect) COMPREPLY=( $(compgen -X '!*.out*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+esac }
+complete -F _g_hydorder_compl g_hydorder
+shopt -s extglob
+_g_kinetics_compl() {
+local p c
+COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -d -d2 -o -o2 -o3 -ee -g -m -h -version -nice -tu -w -xvg -notime -b -e -bfit -efit -T -n -cut -ucut -euf -efu -ei -maxiter -noback -tol -skip -nosplit -nosum -nodiscrete -mult' -- $c)); return 0; fi
+case "$p" in
+-tu) COMPREPLY=( $(compgen -W ' fs ps ns us ms s ' -- $c ));;
+-xvg) COMPREPLY=( $(compgen -W ' xmgrace xmgr none ' -- $c ));;
+-f) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-d) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-d2) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-o) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-o2) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-o3) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-ee) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-g) COMPREPLY=( $(compgen -X '!*.log*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-m) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+esac }
+complete -F _g_kinetics_compl g_kinetics
+shopt -s extglob
 _g_lie_compl() {
 local p c
 COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
@@ -601,43 +729,16 @@ shopt -s extglob
 _g_membed_compl() {
 local p c
 COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
-if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -n -p -o -x -cpi -cpo -c -e -g -ei -rerun -table -tablep -tableb -dhdl -field -table -tablep -tableb -rerun -tpi -tpid -ei -eo -j -jo -ffout -devout -runav -px -pf -mtx -dn -h -version -nice -deffnm -xvg -xyinit -xyend -zinit -zend -nxy -nz -rad -pieces -asymmetry -ndiff -maxwarn -nocompact -v' -- $c)); return 0; fi
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -n -p -o -x -c -e -dat -h -version -nice -xyinit -xyend -zinit -zend -nxy -nz -rad -pieces -asymmetry -ndiff -maxwarn -start -v -mdrun_path' -- $c)); return 0; fi
 case "$p" in
--xvg) COMPREPLY=( $(compgen -W ' xmgrace xmgr none ' -- $c ));;
 -f) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -n) COMPREPLY=( $(compgen -X '!*.ndx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -p) COMPREPLY=( $(compgen -X '!*.top*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -o) COMPREPLY=( $(compgen -X '!*.+(trr|cpt|trj)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -x) COMPREPLY=( $(compgen -X '!*.xtc*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--cpi) COMPREPLY=( $(compgen -X '!*.cpt*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--cpo) COMPREPLY=( $(compgen -X '!*.cpt*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -c) COMPREPLY=( $(compgen -X '!*.+(gro|g96|pdb|brk|ent|esp|xyz)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -e) COMPREPLY=( $(compgen -X '!*.edr*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--g) COMPREPLY=( $(compgen -X '!*.log*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--ei) COMPREPLY=( $(compgen -X '!*.edi*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--rerun) COMPREPLY=( $(compgen -X '!*.+(xtc|trr|cpt|trj|gro|g96|pdb|g87)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--table) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--tablep) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--tableb) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--dhdl) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--field) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--table) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--tablep) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--tableb) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--rerun) COMPREPLY=( $(compgen -X '!*.+(xtc|trr|cpt|trj|gro|g96|pdb|g87)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--tpi) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--tpid) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--ei) COMPREPLY=( $(compgen -X '!*.edi*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--eo) COMPREPLY=( $(compgen -X '!*.edo*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--j) COMPREPLY=( $(compgen -X '!*.gct*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--jo) COMPREPLY=( $(compgen -X '!*.gct*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--ffout) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--devout) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--runav) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--px) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--pf) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--mtx) COMPREPLY=( $(compgen -X '!*.mtx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--dn) COMPREPLY=( $(compgen -X '!*.ndx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-dat) COMPREPLY=( $(compgen -X '!*.dat*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 esac }
 complete -F _g_membed_compl g_membed
 shopt -s extglob
@@ -691,16 +792,50 @@ case "$p" in
 esac }
 complete -F _g_msd_compl g_msd
 shopt -s extglob
+_gmxcheck_compl() {
+local p c
+COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -f2 -s1 -s2 -c -e -e2 -n -m -h -version -nice -vdwfac -bonlo -bonhi -rmsd -tol -abstol -ab -lastener' -- $c)); return 0; fi
+case "$p" in
+-f) COMPREPLY=( $(compgen -X '!*.+(xtc|trr|cpt|trj|gro|g96|pdb|g87)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-f2) COMPREPLY=( $(compgen -X '!*.+(xtc|trr|cpt|trj|gro|g96|pdb|g87)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-s1) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-s2) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-c) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa|gro|g96|pdb|brk|ent)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-e) COMPREPLY=( $(compgen -X '!*.edr*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-e2) COMPREPLY=( $(compgen -X '!*.edr*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-n) COMPREPLY=( $(compgen -X '!*.ndx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-m) COMPREPLY=( $(compgen -X '!*.tex*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+esac }
+complete -F _gmxcheck_compl gmxcheck
+shopt -s extglob
+_gmxdump_compl() {
+local p c
+COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -s -f -e -cp -p -mtx -om -h -version -nice -nonr -sys' -- $c)); return 0; fi
+case "$p" in
+-s) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-f) COMPREPLY=( $(compgen -X '!*.+(xtc|trr|cpt|trj|gro|g96|pdb|g87)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-e) COMPREPLY=( $(compgen -X '!*.edr*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-cp) COMPREPLY=( $(compgen -X '!*.cpt*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-p) COMPREPLY=( $(compgen -X '!*.top*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-mtx) COMPREPLY=( $(compgen -X '!*.mtx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-om) COMPREPLY=( $(compgen -X '!*.mdp*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+esac }
+complete -F _gmxdump_compl gmxdump
+shopt -s extglob
 _g_nmeig_compl() {
 local p c
 COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
-if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -s -of -ol -v -h -version -nice -xvg -nom -first -last' -- $c)); return 0; fi
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -s -of -ol -os -qc -v -h -version -nice -xvg -nom -first -last -maxspec -T -constr -width' -- $c)); return 0; fi
 case "$p" in
 -xvg) COMPREPLY=( $(compgen -W ' xmgrace xmgr none ' -- $c ));;
 -f) COMPREPLY=( $(compgen -X '!*.mtx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--s) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa|gro|g96|pdb|brk|ent)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-s) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -of) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -ol) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-os) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-qc) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -v) COMPREPLY=( $(compgen -X '!*.+(trr|cpt|trj)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 esac }
 complete -F _g_nmeig_compl g_nmeig
@@ -730,6 +865,14 @@ case "$p" in
 esac }
 complete -F _g_nmtraj_compl g_nmtraj
 shopt -s extglob
+_g_options_compl() {
+local p c
+COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -h -version -nice' -- $c)); return 0; fi
+case "$p" in
+esac }
+complete -F _g_options_compl g_options
+shopt -s extglob
 _g_order_compl() {
 local p c
 COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
@@ -752,6 +895,17 @@ case "$p" in
 esac }
 complete -F _g_order_compl g_order
 shopt -s extglob
+_g_pme_error_compl() {
+local p c
+COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -s -o -so -h -version -nice -beta -tune -self -seed -v' -- $c)); return 0; fi
+case "$p" in
+-s) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-o) COMPREPLY=( $(compgen -X '!*.out*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-so) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+esac }
+complete -F _g_pme_error_compl g_pme_error
+shopt -s extglob
 _g_polystat_compl() {
 local p c
 COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
@@ -905,6 +1059,26 @@ case "$p" in
 esac }
 complete -F _g_rmsf_compl g_rmsf
 shopt -s extglob
+_grompp_compl() {
+local p c
+COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -po -c -r -rb -n -p -pp -o -t -e -ref -h -version -nice -v -time -normvsbds -maxwarn -zero -norenum' -- $c)); return 0; fi
+case "$p" in
+-f) COMPREPLY=( $(compgen -X '!*.mdp*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-po) COMPREPLY=( $(compgen -X '!*.mdp*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-c) COMPREPLY=( $(compgen -X '!*.+(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-r) COMPREPLY=( $(compgen -X '!*.+(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-rb) COMPREPLY=( $(compgen -X '!*.+(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-n) COMPREPLY=( $(compgen -X '!*.ndx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-p) COMPREPLY=( $(compgen -X '!*.top*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-pp) COMPREPLY=( $(compgen -X '!*.top*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-o) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-t) COMPREPLY=( $(compgen -X '!*.+(trr|cpt|trj)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-e) COMPREPLY=( $(compgen -X '!*.edr*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-ref) COMPREPLY=( $(compgen -X '!*.+(trr|cpt|trj)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+esac }
+complete -F _grompp_compl grompp
+shopt -s extglob
 _g_rotacf_compl() {
 local p c
 COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
@@ -912,7 +1086,7 @@ if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f
 case "$p" in
 -xvg) COMPREPLY=( $(compgen -W ' xmgrace xmgr none ' -- $c ));;
 -P) COMPREPLY=( $(compgen -W ' 0 1 2 3 ' -- $c ));;
--fitfn) COMPREPLY=( $(compgen -W ' none exp aexp exp_exp vac exp5 exp7 exp9 ' -- $c ));;
+-fitfn) COMPREPLY=( $(compgen -W ' none exp aexp exp_exp vac exp5 exp7 exp9 erffit ' -- $c ));;
 -f) COMPREPLY=( $(compgen -X '!*.+(xtc|trr|cpt|trj|gro|g96|pdb|g87)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -s) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -n) COMPREPLY=( $(compgen -X '!*.ndx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
@@ -944,6 +1118,25 @@ case "$p" in
 esac }
 complete -F _g_saltbr_compl g_saltbr
 shopt -s extglob
+_g_sans_compl() {
+local p c
+COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -s -f -n -d -pr -sq -prframe -sqframe -h -version -nice -b -e -dt -tu -xvg -mode -mcover -nopbc -startq -endq -qstep -seed' -- $c)); return 0; fi
+case "$p" in
+-tu) COMPREPLY=( $(compgen -W ' fs ps ns us ms s ' -- $c ));;
+-xvg) COMPREPLY=( $(compgen -W ' xmgrace xmgr none ' -- $c ));;
+-mode) COMPREPLY=( $(compgen -W ' direct mc ' -- $c ));;
+-s) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-f) COMPREPLY=( $(compgen -X '!*.+(xtc|trr|cpt|trj|gro|g96|pdb|g87)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-n) COMPREPLY=( $(compgen -X '!*.ndx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-d) COMPREPLY=( $(compgen -X '!*.dat*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-pr) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-sq) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-prframe) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-sqframe) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+esac }
+complete -F _g_sans_compl g_sans
+shopt -s extglob
 _g_sas_compl() {
 local p c
 COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
@@ -962,19 +1155,6 @@ case "$p" in
 esac }
 complete -F _g_sas_compl g_sas
 shopt -s extglob
-_g_sdf_compl() {
-local p c
-COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
-if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -n -s -o -r -h -version -nice -b -e -dt -mode -triangle -dtri -bin -grid' -- $c)); return 0; fi
-case "$p" in
--f) COMPREPLY=( $(compgen -X '!*.+(xtc|trr|cpt|trj|gro|g96|pdb|g87)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--n) COMPREPLY=( $(compgen -X '!*.ndx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--s) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa|gro|g96|pdb|brk|ent)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--o) COMPREPLY=( $(compgen -X '!*.dat*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--r) COMPREPLY=( $(compgen -X '!*.+(gro|g96|pdb|brk|ent|esp|xyz)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
-esac }
-complete -F _g_sdf_compl g_sdf
-shopt -s extglob
 _g_select_compl() {
 local p c
 COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
@@ -1093,7 +1273,7 @@ if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f
 case "$p" in
 -xvg) COMPREPLY=( $(compgen -W ' xmgrace xmgr none ' -- $c ));;
 -P) COMPREPLY=( $(compgen -W ' 0 1 2 3 ' -- $c ));;
--fitfn) COMPREPLY=( $(compgen -W ' none exp aexp exp_exp vac exp5 exp7 exp9 ' -- $c ));;
+-fitfn) COMPREPLY=( $(compgen -W ' none exp aexp exp_exp vac exp5 exp7 exp9 erffit ' -- $c ));;
 -f) COMPREPLY=( $(compgen -X '!*.+(trr|cpt|trj)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -s) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa|gro|g96|pdb|brk|ent)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -n) COMPREPLY=( $(compgen -X '!*.ndx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
@@ -1109,7 +1289,7 @@ shopt -s extglob
 _g_traj_compl() {
 local p c
 COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
-if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -s -n -ox -oxt -ov -of -ob -ot -ekt -ekr -vd -cv -cf -av -af -h -version -nice -b -e -dt -tu -w -xvg -com -nopbc -mol -nojump -nox -noy -noz -ng -len -fp -bin -scale' -- $c)); return 0; fi
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -s -n -ox -oxt -ov -of -ob -ot -ekt -ekr -vd -cv -cf -av -af -h -version -nice -b -e -dt -tu -w -xvg -com -nopbc -mol -nojump -nox -noy -noz -ng -len -fp -bin -ctime -scale' -- $c)); return 0; fi
 case "$p" in
 -tu) COMPREPLY=( $(compgen -W ' fs ps ns us ms s ' -- $c ));;
 -xvg) COMPREPLY=( $(compgen -W ' xmgrace xmgr none ' -- $c ));;
@@ -1135,13 +1315,11 @@ shopt -s extglob
 _g_tune_pme_compl() {
 local p c
 COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
-if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -p -err -so -s -o -x -cpi -cpo -c -e -g -dhdl -field -table -tablep -tableb -rerun -tpi -tpid -ei -eo -j -jo -ffout -devout -runav -px -pf -mtx -dn -bo -bx -bcpo -bc -be -bg -beo -bdhdl -bfield -btpi -btpid -bjo -bffout -bdevout -brunav -bpx -bpf -bmtx -bdn -h -version -nice -xvg -np -npstring -nt -r -max -min -npme -upfac -downfac -ntpr -four -steps -resetstep -simsteps -launch -deffnm -ddorder -noddcheck -rdd -rcon -dlb -dds -gcom -v -nocompact -seppot -pforce -reprod -cpt -cpnum -noappend -maxh -multi -replex -reseed -ionize' -- $c)); return 0; fi
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -p -err -so -s -o -x -cpi -cpo -c -e -g -dhdl -field -table -tabletf -tablep -tableb -rerun -tpi -tpid -ei -eo -j -jo -ffout -devout -runav -px -pf -ro -ra -rs -rt -mtx -dn -bo -bx -bcpo -bc -be -bg -beo -bdhdl -bfield -btpi -btpid -bjo -bffout -bdevout -brunav -bpx -bpf -bro -bra -brs -brt -bmtx -bdn -h -version -nice -xvg -np -npstring -ntmpi -r -max -min -npme -fix -rmax -rmin -noscalevdw -ntpr -steps -resetstep -simsteps -launch -nobench -noappend -cpnum' -- $c)); return 0; fi
 case "$p" in
 -xvg) COMPREPLY=( $(compgen -W ' xmgrace xmgr none ' -- $c ));;
 -npstring) COMPREPLY=( $(compgen -W ' -np -n none ' -- $c ));;
 -npme) COMPREPLY=( $(compgen -W ' auto all subset ' -- $c ));;
--ddorder) COMPREPLY=( $(compgen -W ' interleave pp_pme cartesian ' -- $c ));;
--dlb) COMPREPLY=( $(compgen -W ' auto no yes ' -- $c ));;
 -p) COMPREPLY=( $(compgen -X '!*.out*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -err) COMPREPLY=( $(compgen -X '!*.log*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -so) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
@@ -1156,13 +1334,14 @@ case "$p" in
 -dhdl) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -field) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -table) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-tabletf) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -tablep) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -tableb) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -rerun) COMPREPLY=( $(compgen -X '!*.+(xtc|trr|cpt|trj|gro|g96|pdb|g87)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -tpi) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -tpid) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -ei) COMPREPLY=( $(compgen -X '!*.edi*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--eo) COMPREPLY=( $(compgen -X '!*.edo*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-eo) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -j) COMPREPLY=( $(compgen -X '!*.gct*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -jo) COMPREPLY=( $(compgen -X '!*.gct*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -ffout) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
@@ -1170,6 +1349,10 @@ case "$p" in
 -runav) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -px) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -pf) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-ro) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-ra) COMPREPLY=( $(compgen -X '!*.log*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-rs) COMPREPLY=( $(compgen -X '!*.log*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-rt) COMPREPLY=( $(compgen -X '!*.log*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -mtx) COMPREPLY=( $(compgen -X '!*.mtx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -dn) COMPREPLY=( $(compgen -X '!*.ndx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -bo) COMPREPLY=( $(compgen -X '!*.+(trr|cpt|trj)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
@@ -1178,7 +1361,7 @@ case "$p" in
 -bc) COMPREPLY=( $(compgen -X '!*.+(gro|g96|pdb|brk|ent|esp|xyz)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -be) COMPREPLY=( $(compgen -X '!*.edr*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -bg) COMPREPLY=( $(compgen -X '!*.log*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--beo) COMPREPLY=( $(compgen -X '!*.edo*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-beo) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -bdhdl) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -bfield) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -btpi) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
@@ -1189,6 +1372,10 @@ case "$p" in
 -brunav) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -bpx) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -bpf) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-bro) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-bra) COMPREPLY=( $(compgen -X '!*.log*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-brs) COMPREPLY=( $(compgen -X '!*.log*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-brt) COMPREPLY=( $(compgen -X '!*.log*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -bmtx) COMPREPLY=( $(compgen -X '!*.mtx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -bdn) COMPREPLY=( $(compgen -X '!*.ndx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 esac }
@@ -1212,36 +1399,38 @@ shopt -s extglob
 _g_velacc_compl() {
 local p c
 COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
-if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -s -n -o -h -version -nice -b -e -dt -w -xvg -m -mol -acflen -nonormalize -P -fitfn -ncskip -beginfit -endfit' -- $c)); return 0; fi
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -s -n -o -os -h -version -nice -b -e -dt -w -xvg -m -norecip -mol -acflen -nonormalize -P -fitfn -ncskip -beginfit -endfit' -- $c)); return 0; fi
 case "$p" in
 -xvg) COMPREPLY=( $(compgen -W ' xmgrace xmgr none ' -- $c ));;
 -P) COMPREPLY=( $(compgen -W ' 0 1 2 3 ' -- $c ));;
--fitfn) COMPREPLY=( $(compgen -W ' none exp aexp exp_exp vac exp5 exp7 exp9 ' -- $c ));;
+-fitfn) COMPREPLY=( $(compgen -W ' none exp aexp exp_exp vac exp5 exp7 exp9 erffit ' -- $c ));;
 -f) COMPREPLY=( $(compgen -X '!*.+(trr|cpt|trj)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -s) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa|gro|g96|pdb|brk|ent)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -n) COMPREPLY=( $(compgen -X '!*.ndx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -o) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-os) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 esac }
 complete -F _g_velacc_compl g_velacc
 shopt -s extglob
 _g_wham_compl() {
 local p c
 COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
-if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -ix -if -it -ip -o -hist -bsres -bsprof -tab -wcorr -h -version -nice -xvg -min -max -noauto -bins -temp -tol -v -b -e -dt -histonly -boundsonly -nolog -unit -zprof0 -cycl -alpha -flip -hist-eq -nBootstrap -bs-dt -bs-seed -nohistbs -histbs-block -vbs' -- $c)); return 0; fi
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -ix -if -it -ip -o -hist -oiact -iiact -bsres -bsprof -tab -h -version -nice -xvg -min -max -noauto -bins -temp -tol -v -b -e -dt -histonly -boundsonly -nolog -unit -zprof0 -cycl -sym -ac -acsig -ac-trestart -nBootstrap -bs-method -bs-tau -bs-seed -histbs-block -vbs' -- $c)); return 0; fi
 case "$p" in
 -xvg) COMPREPLY=( $(compgen -W ' xmgrace xmgr none ' -- $c ));;
 -unit) COMPREPLY=( $(compgen -W ' kJ kCal kT ' -- $c ));;
--cycl) COMPREPLY=( $(compgen -W ' no yes weighted ' -- $c ));;
+-bs-method) COMPREPLY=( $(compgen -W ' b-hist hist traj traj-gauss ' -- $c ));;
 -ix) COMPREPLY=( $(compgen -X '!*.dat*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -if) COMPREPLY=( $(compgen -X '!*.dat*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -it) COMPREPLY=( $(compgen -X '!*.dat*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -ip) COMPREPLY=( $(compgen -X '!*.dat*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -o) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -hist) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-oiact) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-iiact) COMPREPLY=( $(compgen -X '!*.dat*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -bsres) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -bsprof) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -tab) COMPREPLY=( $(compgen -X '!*.dat*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--wcorr) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 esac }
 complete -F _g_wham_compl g_wham
 shopt -s extglob
@@ -1276,113 +1465,10 @@ case "$p" in
 esac }
 complete -F _g_xrama_compl g_xrama
 shopt -s extglob
-_genbox_compl() {
-local p c
-COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
-if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -cp -cs -ci -o -p -h -version -nice -box -nmol -try -seed -vdwd -shell -maxsol -vel' -- $c)); return 0; fi
-case "$p" in
--cp) COMPREPLY=( $(compgen -X '!*.+(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--cs) COMPREPLY=( $(compgen -X '!*.+(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--ci) COMPREPLY=( $(compgen -X '!*.+(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--o) COMPREPLY=( $(compgen -X '!*.+(gro|g96|pdb|brk|ent|esp|xyz)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--p) COMPREPLY=( $(compgen -X '!*.top*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
-esac }
-complete -F _genbox_compl genbox
-shopt -s extglob
-_genconf_compl() {
-local p c
-COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
-if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -o -trj -h -version -nice -nbox -dist -seed -rot -shuffle -sort -block -nmolat -maxrot -norenumber' -- $c)); return 0; fi
-case "$p" in
--f) COMPREPLY=( $(compgen -X '!*.+(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--o) COMPREPLY=( $(compgen -X '!*.+(gro|g96|pdb|brk|ent|esp|xyz)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--trj) COMPREPLY=( $(compgen -X '!*.+(xtc|trr|cpt|trj|gro|g96|pdb|g87)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
-esac }
-complete -F _genconf_compl genconf
-shopt -s extglob
-_genion_compl() {
-local p c
-COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
-if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -s -table -n -o -g -pot -p -h -version -nice -xvg -np -pname -pq -nn -nname -nq -rmin -norandom -seed -scale -conc -neutral' -- $c)); return 0; fi
-case "$p" in
--xvg) COMPREPLY=( $(compgen -W ' xmgrace xmgr none ' -- $c ));;
--s) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--table) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--n) COMPREPLY=( $(compgen -X '!*.ndx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--o) COMPREPLY=( $(compgen -X '!*.+(gro|g96|pdb|brk|ent|esp|xyz)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--g) COMPREPLY=( $(compgen -X '!*.log*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--pot) COMPREPLY=( $(compgen -X '!*.pdb*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--p) COMPREPLY=( $(compgen -X '!*.top*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
-esac }
-complete -F _genion_compl genion
-shopt -s extglob
-_genrestr_compl() {
-local p c
-COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
-if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -n -o -of -h -version -nice -fc -freeze -disre -disre_dist -disre_frac -disre_up2 -cutoff -constr' -- $c)); return 0; fi
-case "$p" in
--f) COMPREPLY=( $(compgen -X '!*.+(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--n) COMPREPLY=( $(compgen -X '!*.ndx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--o) COMPREPLY=( $(compgen -X '!*.itp*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--of) COMPREPLY=( $(compgen -X '!*.ndx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
-esac }
-complete -F _genrestr_compl genrestr
-shopt -s extglob
-_gmxcheck_compl() {
-local p c
-COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
-if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -f2 -s1 -s2 -c -e -e2 -n -m -h -version -nice -vdwfac -bonlo -bonhi -rmsd -tol -abstol -ab -lastener' -- $c)); return 0; fi
-case "$p" in
--f) COMPREPLY=( $(compgen -X '!*.+(xtc|trr|cpt|trj|gro|g96|pdb|g87)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--f2) COMPREPLY=( $(compgen -X '!*.+(xtc|trr|cpt|trj|gro|g96|pdb|g87)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--s1) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--s2) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--c) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa|gro|g96|pdb|brk|ent)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--e) COMPREPLY=( $(compgen -X '!*.edr*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--e2) COMPREPLY=( $(compgen -X '!*.edr*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--n) COMPREPLY=( $(compgen -X '!*.ndx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--m) COMPREPLY=( $(compgen -X '!*.tex*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
-esac }
-complete -F _gmxcheck_compl gmxcheck
-shopt -s extglob
-_gmxdump_compl() {
-local p c
-COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
-if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -s -f -e -cp -p -mtx -om -h -version -nice -nonr -sys' -- $c)); return 0; fi
-case "$p" in
--s) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--f) COMPREPLY=( $(compgen -X '!*.+(xtc|trr|cpt|trj|gro|g96|pdb|g87)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--e) COMPREPLY=( $(compgen -X '!*.edr*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--cp) COMPREPLY=( $(compgen -X '!*.cpt*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--p) COMPREPLY=( $(compgen -X '!*.top*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--mtx) COMPREPLY=( $(compgen -X '!*.mtx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--om) COMPREPLY=( $(compgen -X '!*.mdp*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
-esac }
-complete -F _gmxdump_compl gmxdump
-shopt -s extglob
-_grompp_compl() {
-local p c
-COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
-if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -po -c -r -rb -n -p -pp -o -t -e -h -version -nice -v -time -normvsbds -maxwarn -zero -norenum' -- $c)); return 0; fi
-case "$p" in
--f) COMPREPLY=( $(compgen -X '!*.mdp*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--po) COMPREPLY=( $(compgen -X '!*.mdp*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--c) COMPREPLY=( $(compgen -X '!*.+(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--r) COMPREPLY=( $(compgen -X '!*.+(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--rb) COMPREPLY=( $(compgen -X '!*.+(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--n) COMPREPLY=( $(compgen -X '!*.ndx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--p) COMPREPLY=( $(compgen -X '!*.top*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--pp) COMPREPLY=( $(compgen -X '!*.top*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--o) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--t) COMPREPLY=( $(compgen -X '!*.+(trr|cpt|trj)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--e) COMPREPLY=( $(compgen -X '!*.edr*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
-esac }
-complete -F _grompp_compl grompp
-shopt -s extglob
 _make_edi_compl() {
 local p c
 COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
-if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -eig -s -n -tar -ori -o -h -version -nice -xvg -mon -linfix -linacc -flood -radfix -radacc -radcon -outfrq -slope -maxedsteps -deltaF0 -deltaF -tau -eqsteps -Eflnull -T -alpha -linstep -accdir -radstep -restrain -hessian -harmonic' -- $c)); return 0; fi
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -eig -s -n -tar -ori -o -h -version -nice -xvg -mon -linfix -linacc -radfix -radacc -radcon -flood -outfrq -slope -linstep -accdir -radstep -maxedsteps -eqsteps -deltaF0 -deltaF -tau -Eflnull -T -alpha -restrain -hessian -harmonic -constF' -- $c)); return 0; fi
 case "$p" in
 -xvg) COMPREPLY=( $(compgen -W ' xmgrace xmgr none ' -- $c ));;
 -f) COMPREPLY=( $(compgen -X '!*.+(trr|cpt|trj)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
@@ -1409,11 +1495,12 @@ shopt -s extglob
 _mdrun_compl() {
 local p c
 COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
-if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -s -o -x -cpi -cpo -c -e -g -dhdl -field -table -tablep -tableb -rerun -tpi -tpid -ei -eo -j -jo -ffout -devout -runav -px -pf -mtx -dn -h -version -nice -deffnm -xvg -pd -dd -nt -npme -ddorder -noddcheck -rdd -rcon -dlb -dds -gcom -v -nocompact -seppot -pforce -reprod -cpt -cpnum -noappend -maxh -multi -replex -reseed -ionize' -- $c)); return 0; fi
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -s -o -x -cpi -cpo -c -e -g -dhdl -field -table -tabletf -tablep -tableb -rerun -tpi -tpid -ei -eo -j -jo -ffout -devout -runav -px -pf -ro -ra -rs -rt -mtx -dn -multidir -membed -mp -mn -h -version -nice -deffnm -xvg -pd -dd -ddorder -npme -nt -ntmpi -ntomp -ntomp_pme -nopin -pinht -pinoffset -gpu_id -noddcheck -rdd -rcon -dlb -dds -gcom -nb -notunepme -testverlet -v -nocompact -seppot -pforce -reprod -cpt -cpnum -noappend -nsteps -maxh -multi -replex -nex -reseed -ionize' -- $c)); return 0; fi
 case "$p" in
 -xvg) COMPREPLY=( $(compgen -W ' xmgrace xmgr none ' -- $c ));;
 -ddorder) COMPREPLY=( $(compgen -W ' interleave pp_pme cartesian ' -- $c ));;
 -dlb) COMPREPLY=( $(compgen -W ' auto no yes ' -- $c ));;
+-nb) COMPREPLY=( $(compgen -W ' auto cpu gpu gpu_cpu ' -- $c ));;
 -s) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -o) COMPREPLY=( $(compgen -X '!*.+(trr|cpt|trj)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -x) COMPREPLY=( $(compgen -X '!*.xtc*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
@@ -1425,13 +1512,14 @@ case "$p" in
 -dhdl) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -field) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -table) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-tabletf) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -tablep) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -tableb) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -rerun) COMPREPLY=( $(compgen -X '!*.+(xtc|trr|cpt|trj|gro|g96|pdb|g87)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -tpi) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -tpid) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -ei) COMPREPLY=( $(compgen -X '!*.edi*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
--eo) COMPREPLY=( $(compgen -X '!*.edo*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-eo) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -j) COMPREPLY=( $(compgen -X '!*.gct*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -jo) COMPREPLY=( $(compgen -X '!*.gct*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -ffout) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
@@ -1439,11 +1527,67 @@ case "$p" in
 -runav) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -px) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -pf) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-ro) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-ra) COMPREPLY=( $(compgen -X '!*.log*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-rs) COMPREPLY=( $(compgen -X '!*.log*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-rt) COMPREPLY=( $(compgen -X '!*.log*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -mtx) COMPREPLY=( $(compgen -X '!*.mtx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -dn) COMPREPLY=( $(compgen -X '!*.ndx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-multidir) COMPREPLY=( $(compgen -X '!*.rundir*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-membed) COMPREPLY=( $(compgen -X '!*.dat*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-mp) COMPREPLY=( $(compgen -X '!*.top*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-mn) COMPREPLY=( $(compgen -X '!*.ndx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 esac }
 complete -F _mdrun_compl mdrun
 shopt -s extglob
+_mdrun_mpi_compl() {
+local p c
+COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -s -o -x -cpi -cpo -c -e -g -dhdl -field -table -tabletf -tablep -tableb -rerun -tpi -tpid -ei -eo -j -jo -ffout -devout -runav -px -pf -ro -ra -rs -rt -mtx -dn -multidir -membed -mp -mn -h -version -nice -deffnm -xvg -pd -dd -ddorder -npme -nt -ntmpi -ntomp -ntomp_pme -nopin -pinht -pinoffset -gpu_id -noddcheck -rdd -rcon -dlb -dds -gcom -nb -notunepme -testverlet -v -nocompact -seppot -pforce -reprod -cpt -cpnum -noappend -nsteps -maxh -multi -replex -nex -reseed -ionize' -- $c)); return 0; fi
+case "$p" in
+-xvg) COMPREPLY=( $(compgen -W ' xmgrace xmgr none ' -- $c ));;
+-ddorder) COMPREPLY=( $(compgen -W ' interleave pp_pme cartesian ' -- $c ));;
+-dlb) COMPREPLY=( $(compgen -W ' auto no yes ' -- $c ));;
+-nb) COMPREPLY=( $(compgen -W ' auto cpu gpu gpu_cpu ' -- $c ));;
+-s) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-o) COMPREPLY=( $(compgen -X '!*.+(trr|cpt|trj)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-x) COMPREPLY=( $(compgen -X '!*.xtc*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-cpi) COMPREPLY=( $(compgen -X '!*.cpt*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-cpo) COMPREPLY=( $(compgen -X '!*.cpt*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-c) COMPREPLY=( $(compgen -X '!*.+(gro|g96|pdb|brk|ent|esp|xyz)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-e) COMPREPLY=( $(compgen -X '!*.edr*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-g) COMPREPLY=( $(compgen -X '!*.log*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-dhdl) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-field) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-table) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-tabletf) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-tablep) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-tableb) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-rerun) COMPREPLY=( $(compgen -X '!*.+(xtc|trr|cpt|trj|gro|g96|pdb|g87)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-tpi) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-tpid) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-ei) COMPREPLY=( $(compgen -X '!*.edi*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-eo) COMPREPLY=( $(compgen -X '!*.edo*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-j) COMPREPLY=( $(compgen -X '!*.gct*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-jo) COMPREPLY=( $(compgen -X '!*.gct*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-ffout) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-devout) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-runav) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-px) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-pf) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-ro) COMPREPLY=( $(compgen -X '!*.xvg*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-ra) COMPREPLY=( $(compgen -X '!*.log*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-rs) COMPREPLY=( $(compgen -X '!*.log*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-rt) COMPREPLY=( $(compgen -X '!*.log*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-mtx) COMPREPLY=( $(compgen -X '!*.mtx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-dn) COMPREPLY=( $(compgen -X '!*.ndx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-multidir) COMPREPLY=( $(compgen -X '!*.rundir*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-membed) COMPREPLY=( $(compgen -X '!*.dat*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-mp) COMPREPLY=( $(compgen -X '!*.top*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+-mn) COMPREPLY=( $(compgen -X '!*.ndx*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
+esac }
+complete -F _mdrun_mpi_compl mdrun_mpi
+shopt -s extglob
 _mk_angndx_compl() {
 local p c
 COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
@@ -1469,9 +1613,10 @@ shopt -s extglob
 _pdb2gmx_compl() {
 local p c
 COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
-if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -o -p -i -n -q -h -version -nice -chainsep -ff -water -inter -ss -ter -lys -arg -asp -glu -gln -his -angle -dist -una -ignh -missing -v -posrefc -vsite -heavyh -deuterate -nochargegrp -nocmap -renum -rtpres' -- $c)); return 0; fi
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -o -p -i -n -q -h -version -nice -chainsep -merge -ff -water -inter -ss -ter -lys -arg -asp -glu -gln -his -angle -dist -una -ignh -missing -v -posrefc -vsite -heavyh -deuterate -nochargegrp -nocmap -renum -rtpres' -- $c)); return 0; fi
 case "$p" in
 -chainsep) COMPREPLY=( $(compgen -W ' id_or_ter id_and_ter ter id interactive ' -- $c ));;
+-merge) COMPREPLY=( $(compgen -W ' no all interactive ' -- $c ));;
 -water) COMPREPLY=( $(compgen -W ' select none spc spce tip3p tip4p tip5p ' -- $c ));;
 -vsite) COMPREPLY=( $(compgen -W ' none hydrogens aromatics ' -- $c ));;
 -f) COMPREPLY=( $(compgen -X '!*.+(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
@@ -1486,7 +1631,7 @@ shopt -s extglob
 _tpbconv_compl() {
 local p c
 COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
-if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -s -f -e -n -o -h -version -nice -extend -until -nsteps -time -zeroq -novel -nocont' -- $c)); return 0; fi
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -s -f -e -n -o -h -version -nice -extend -until -nsteps -time -zeroq -novel -nocont -init_fep_state' -- $c)); return 0; fi
 case "$p" in
 -s) COMPREPLY=( $(compgen -X '!*.+(tpr|tpb|tpa)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
 -f) COMPREPLY=( $(compgen -X '!*.+(trr|cpt|trj)*(.gz|.Z)' -f $c ; compgen -S '/' -X '.*' -d $c ));;
@@ -1513,7 +1658,7 @@ shopt -s extglob
 _trjconv_compl() {
 local p c
 COMPREPLY=() c=${COMP_WORDS[COMP_CWORD]} p=${COMP_WORDS[COMP_CWORD-1]}
-if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -o -s -n -fr -sub -drop -h -version -nice -b -e -tu -w -xvg -skip -dt -round -dump -t0 -timestep -pbc -ur -center -boxcenter -box -trans -shift -fit -ndec -novel -force -trunc -exec -app -split -sep -nzero -dropunder -dropover -conect' -- $c)); return 0; fi
+if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen  -W ' -f -o -s -n -fr -sub -drop -h -version -nice -b -e -tu -w -xvg -skip -dt -round -dump -t0 -timestep -pbc -ur -center -boxcenter -box -clustercenter -trans -shift -fit -ndec -novel -force -trunc -exec -app -split -sep -nzero -dropunder -dropover -conect' -- $c)); return 0; fi
 case "$p" in
 -tu) COMPREPLY=( $(compgen -W ' fs ps ns us ms s ' -- $c ));;
 -xvg) COMPREPLY=( $(compgen -W ' xmgrace xmgr none ' -- $c ));;
index 73364576afea198b151e7f7168543114d641ba79..926388da685d40fdafa88251084cd4e4e7115563 100644 (file)
@@ -1,45 +1,57 @@
-complete do_dssp "n/-tu/( fs ps ns us ms s)/" "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-ssdump/f:*.dat{,.gz,.Z}/" "n/-map/f:*.map{,.gz,.Z}/" "n/-o/f:*.xpm{,.gz,.Z}/" "n/-sc/f:*.xvg{,.gz,.Z}/" "n/-a/f:*.xpm{,.gz,.Z}/" "n/-ta/f:*.xvg{,.gz,.Z}/" "n/-aa/f:*.xvg{,.gz,.Z}/" "c/-/( f s n ssdump map o sc a ta aa h version nice b e dt tu w xvg sss)/"
-complete editconf "n/-bt/( triclinic cubic dodecahedron octahedron)/" "n/-f/f:*.{gro,g96,pdb,brk,ent,esp,xyz,tpr,tpb,tpa}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-o/f:*.{gro,g96,pdb,brk,ent,esp,xyz}{,.gz,.Z}/" "n/-mead/f:*.pqr{,.gz,.Z}/" "n/-bf/f:*.dat{,.gz,.Z}/" "c/-/( f n o mead bf h version nice w ndef bt box angles d c center aligncenter align translate rotate princ scale density pbc grasp rvdw sig56 vdwread atom legend label conect)/"
-complete eneconv "n/-f/f:*.edr{,.gz,.Z}/" "n/-o/f:*.edr{,.gz,.Z}/" "c/-/( f o h version nice b e dt offset settime nosort scalefac noerror)/"
+complete do_dssp "n/-tu/( fs ps ns us ms s)/" "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-ssdump/f:*.dat{,.gz,.Z}/" "n/-map/f:*.map{,.gz,.Z}/" "n/-o/f:*.xpm{,.gz,.Z}/" "n/-sc/f:*.xvg{,.gz,.Z}/" "n/-a/f:*.xpm{,.gz,.Z}/" "n/-ta/f:*.xvg{,.gz,.Z}/" "n/-aa/f:*.xvg{,.gz,.Z}/" "c/-/( f s n ssdump map o sc a ta aa h version nice b e dt tu w xvg sss ver)/"
+complete editconf "n/-bt/( triclinic cubic dodecahedron octahedron)/" "n/-f/f:*.{gro,g96,pdb,brk,ent,esp,xyz,tpr,tpb,tpa}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-o/f:*.{gro,g96,pdb,brk,ent,esp,xyz}{,.gz,.Z}/" "n/-mead/f:*.pqr{,.gz,.Z}/" "n/-bf/f:*.dat{,.gz,.Z}/" "c/-/( f n o mead bf h version nice w ndef bt box angles d c center aligncenter align translate rotate princ scale density pbc resnr grasp rvdw sig56 vdwread atom legend label conect)/"
+complete eneconv "n/-f/f:*.edr{,.gz,.Z}/" "n/-o/f:*.edr{,.gz,.Z}/" "c/-/( f o h version nice b e dt offset settime nosort rmdh scalefac noerror)/"
 complete g_anadock "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.pdb{,.gz,.Z}/" "n/-ox/f:*.pdb{,.gz,.Z}/" "n/-od/f:*.xvg{,.gz,.Z}/" "n/-of/f:*.xvg{,.gz,.Z}/" "n/-g/f:*.log{,.gz,.Z}/" "c/-/( f ox od of g h version nice xvg free norms cutoff)/"
 complete g_anaeig "n/-tu/( fs ps ns us ms s)/" "n/-xvg/( xmgrace xmgr none)/" "n/-v/f:*.{trr,cpt,trj}{,.gz,.Z}/" "n/-v2/f:*.{trr,cpt,trj}{,.gz,.Z}/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-eig/f:*.xvg{,.gz,.Z}/" "n/-eig2/f:*.xvg{,.gz,.Z}/" "n/-comp/f:*.xvg{,.gz,.Z}/" "n/-rmsf/f:*.xvg{,.gz,.Z}/" "n/-proj/f:*.xvg{,.gz,.Z}/" "n/-2d/f:*.xvg{,.gz,.Z}/" "n/-3d/f:*.{gro,g96,pdb,brk,ent,esp,xyz}{,.gz,.Z}/" "n/-filt/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-extr/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-over/f:*.xvg{,.gz,.Z}/" "n/-inpr/f:*.xpm{,.gz,.Z}/" "c/-/( v v2 f s n eig eig2 comp rmsf proj 2d 3d filt extr over inpr h version nice b e dt tu w xvg first last skip max nframes split entropy temp nevskip)/"
-complete g_analyze "n/-xvg/( xmgrace xmgr none)/" "n/-errbar/( none stddev error 90)/" "n/-P/( 0 1 2 3)/" "n/-fitfn/( none exp aexp exp_exp vac exp5 exp7 exp9)/" "n/-f/f:*.xvg{,.gz,.Z}/" "n/-ac/f:*.xvg{,.gz,.Z}/" "n/-msd/f:*.xvg{,.gz,.Z}/" "n/-cc/f:*.xvg{,.gz,.Z}/" "n/-dist/f:*.xvg{,.gz,.Z}/" "n/-av/f:*.xvg{,.gz,.Z}/" "n/-ee/f:*.xvg{,.gz,.Z}/" "n/-bal/f:*.xvg{,.gz,.Z}/" "n/-g/f:*.log{,.gz,.Z}/" "c/-/( f ac msd cc dist av ee bal g h version nice w xvg notime b e n d bw errbar integrate aver_start xydy regression luzar temp fitstart fitend smooth filter power nosubav oneacf acflen nonormalize P fitfn ncskip beginfit endfit)/"
-complete g_angle "n/-xvg/( xmgrace xmgr none)/" "n/-type/( angle dihedral improper ryckaert-bellemans)/" "n/-P/( 0 1 2 3)/" "n/-fitfn/( none exp aexp exp_exp vac exp5 exp7 exp9)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-od/f:*.xvg{,.gz,.Z}/" "n/-ov/f:*.xvg{,.gz,.Z}/" "n/-of/f:*.xvg{,.gz,.Z}/" "n/-ot/f:*.xvg{,.gz,.Z}/" "n/-oh/f:*.xvg{,.gz,.Z}/" "n/-oc/f:*.xvg{,.gz,.Z}/" "n/-or/f:*.trr{,.gz,.Z}/" "c/-/( f n od ov of ot oh oc or h version nice b e dt w xvg type all binwidth noperiodic chandler avercorr acflen nonormalize P fitfn ncskip beginfit endfit)/"
-complete g_bar "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.xvg{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-oi/f:*.xvg{,.gz,.Z}/" "n/-oh/f:*.xvg{,.gz,.Z}/" "n/-g/f:*.edr{,.gz,.Z}/" "c/-/( f o oi oh g h version nice w xvg b e temp prec nbmin nbmax nbin)/"
+complete g_analyze "n/-xvg/( xmgrace xmgr none)/" "n/-errbar/( none stddev error 90)/" "n/-P/( 0 1 2 3)/" "n/-fitfn/( none exp aexp exp_exp vac exp5 exp7 exp9 erffit)/" "n/-f/f:*.xvg{,.gz,.Z}/" "n/-ac/f:*.xvg{,.gz,.Z}/" "n/-msd/f:*.xvg{,.gz,.Z}/" "n/-cc/f:*.xvg{,.gz,.Z}/" "n/-dist/f:*.xvg{,.gz,.Z}/" "n/-av/f:*.xvg{,.gz,.Z}/" "n/-ee/f:*.xvg{,.gz,.Z}/" "n/-bal/f:*.xvg{,.gz,.Z}/" "n/-g/f:*.log{,.gz,.Z}/" "c/-/( f ac msd cc dist av ee bal g h version nice w xvg notime b e n d bw errbar integrate aver_start xydy regression luzar temp fitstart fitend smooth filter power nosubav oneacf acflen nonormalize P fitfn ncskip beginfit endfit)/"
+complete g_angle "n/-xvg/( xmgrace xmgr none)/" "n/-type/( angle dihedral improper ryckaert-bellemans)/" "n/-P/( 0 1 2 3)/" "n/-fitfn/( none exp aexp exp_exp vac exp5 exp7 exp9 erffit)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-od/f:*.xvg{,.gz,.Z}/" "n/-ov/f:*.xvg{,.gz,.Z}/" "n/-of/f:*.xvg{,.gz,.Z}/" "n/-ot/f:*.xvg{,.gz,.Z}/" "n/-oh/f:*.xvg{,.gz,.Z}/" "n/-oc/f:*.xvg{,.gz,.Z}/" "n/-or/f:*.trr{,.gz,.Z}/" "c/-/( f n od ov of ot oh oc or h version nice b e dt w xvg type all binwidth noperiodic chandler avercorr acflen nonormalize P fitfn ncskip beginfit endfit)/"
+complete g_bar "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.xvg{,.gz,.Z}/" "n/-g/f:*.edr{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-oi/f:*.xvg{,.gz,.Z}/" "n/-oh/f:*.xvg{,.gz,.Z}/" "c/-/( f g o oi oh h version nice w xvg b e temp prec nbmin nbmax nbin extp)/"
 complete g_bond "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-l/f:*.log{,.gz,.Z}/" "n/-d/f:*.xvg{,.gz,.Z}/" "c/-/( f n s o l d h version nice b e dt w xvg blen tol noaver noaverdist)/"
 complete g_bundle "n/-tu/( fs ps ns us ms s)/" "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-ol/f:*.xvg{,.gz,.Z}/" "n/-od/f:*.xvg{,.gz,.Z}/" "n/-oz/f:*.xvg{,.gz,.Z}/" "n/-ot/f:*.xvg{,.gz,.Z}/" "n/-otr/f:*.xvg{,.gz,.Z}/" "n/-otl/f:*.xvg{,.gz,.Z}/" "n/-ok/f:*.xvg{,.gz,.Z}/" "n/-okr/f:*.xvg{,.gz,.Z}/" "n/-okl/f:*.xvg{,.gz,.Z}/" "n/-oa/f:*.pdb{,.gz,.Z}/" "c/-/( f s n ol od oz ot otr otl ok okr okl oa h version nice b e dt tu xvg na z)/"
-complete g_chi "n/-xvg/( xmgrace xmgr none)/" "n/-maxchi/( 0 1 2 3 4 5 6)/" "n/-P/( 0 1 2 3)/" "n/-fitfn/( none exp aexp exp_exp vac exp5 exp7 exp9)/" "n/-s/f:*.{gro,g96,pdb,brk,ent,esp,xyz,tpr,tpb,tpa}{,.gz,.Z}/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-p/f:*.pdb{,.gz,.Z}/" "n/-ss/f:*.dat{,.gz,.Z}/" "n/-jc/f:*.xvg{,.gz,.Z}/" "n/-corr/f:*.xvg{,.gz,.Z}/" "n/-g/f:*.log{,.gz,.Z}/" "n/-ot/f:*.xvg{,.gz,.Z}/" "n/-oh/f:*.xvg{,.gz,.Z}/" "n/-rt/f:*.xvg{,.gz,.Z}/" "n/-cp/f:*.xvg{,.gz,.Z}/" "c/-/( s f o p ss jc corr g ot oh rt cp h version nice b e dt w xvg r0 phi psi omega rama viol noperiodic all rad shift binwidth core_rotamer maxchi nonormhisto ramomega bfact chi_prod HChi bmax acflen nonormalize P fitfn ncskip beginfit endfit)/"
-complete g_cluster "n/-tu/( fs ps ns us ms s)/" "n/-xvg/( xmgrace xmgr none)/" "n/-method/( linkage jarvis-patrick monte-carlo diagonalization gromos)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-dm/f:*.xpm{,.gz,.Z}/" "n/-o/f:*.xpm{,.gz,.Z}/" "n/-g/f:*.log{,.gz,.Z}/" "n/-dist/f:*.xvg{,.gz,.Z}/" "n/-ev/f:*.xvg{,.gz,.Z}/" "n/-sz/f:*.xvg{,.gz,.Z}/" "n/-tr/f:*.xpm{,.gz,.Z}/" "n/-ntr/f:*.xvg{,.gz,.Z}/" "n/-clid/f:*.xvg{,.gz,.Z}/" "n/-cl/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "c/-/( f s n dm o g dist ev sz tr ntr clid cl h version nice b e dt tu w xvg dista nlevels cutoff nofit max skip av wcl nst rmsmin method minstruct binary M P seed niter kT)/"
+complete g_chi "n/-xvg/( xmgrace xmgr none)/" "n/-maxchi/( 0 1 2 3 4 5 6)/" "n/-P/( 0 1 2 3)/" "n/-fitfn/( none exp aexp exp_exp vac exp5 exp7 exp9 erffit)/" "n/-s/f:*.{gro,g96,pdb,brk,ent,esp,xyz,tpr,tpb,tpa}{,.gz,.Z}/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-p/f:*.pdb{,.gz,.Z}/" "n/-ss/f:*.dat{,.gz,.Z}/" "n/-jc/f:*.xvg{,.gz,.Z}/" "n/-corr/f:*.xvg{,.gz,.Z}/" "n/-g/f:*.log{,.gz,.Z}/" "n/-ot/f:*.xvg{,.gz,.Z}/" "n/-oh/f:*.xvg{,.gz,.Z}/" "n/-rt/f:*.xvg{,.gz,.Z}/" "n/-cp/f:*.xvg{,.gz,.Z}/" "c/-/( s f o p ss jc corr g ot oh rt cp h version nice b e dt w xvg r0 phi psi omega rama viol noperiodic all rad shift binwidth core_rotamer maxchi nonormhisto ramomega bfact chi_prod HChi bmax acflen nonormalize P fitfn ncskip beginfit endfit)/"
+complete g_cluster "n/-tu/( fs ps ns us ms s)/" "n/-xvg/( xmgrace xmgr none)/" "n/-method/( linkage jarvis-patrick monte-carlo diagonalization gromos)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-dm/f:*.xpm{,.gz,.Z}/" "n/-o/f:*.xpm{,.gz,.Z}/" "n/-g/f:*.log{,.gz,.Z}/" "n/-dist/f:*.xvg{,.gz,.Z}/" "n/-ev/f:*.xvg{,.gz,.Z}/" "n/-sz/f:*.xvg{,.gz,.Z}/" "n/-tr/f:*.xpm{,.gz,.Z}/" "n/-ntr/f:*.xvg{,.gz,.Z}/" "n/-clid/f:*.xvg{,.gz,.Z}/" "n/-cl/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "c/-/( f s n dm o g dist ev sz tr ntr clid cl h version nice b e dt tu w xvg dista nlevels cutoff nofit max skip av wcl nst rmsmin method minstruct binary M P seed niter kT nopbc)/"
 complete g_clustsize "n/-tu/( fs ps ns us ms s)/" "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.tpr{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-o/f:*.xpm{,.gz,.Z}/" "n/-ow/f:*.xpm{,.gz,.Z}/" "n/-nc/f:*.xvg{,.gz,.Z}/" "n/-mc/f:*.xvg{,.gz,.Z}/" "n/-ac/f:*.xvg{,.gz,.Z}/" "n/-hc/f:*.xvg{,.gz,.Z}/" "n/-temp/f:*.xvg{,.gz,.Z}/" "n/-mcn/f:*.ndx{,.gz,.Z}/" "c/-/( f s n o ow nc mc ac hc temp mcn h version nice b e dt tu w xvg cut mol nopbc nskip nlevels ndf rgblo rgbhi)/"
 complete g_confrms "n/-f1/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-f2/f:*.{gro,g96,pdb,brk,ent,esp,xyz,tpr,tpb,tpa}{,.gz,.Z}/" "n/-o/f:*.{gro,g96,pdb,brk,ent,esp,xyz}{,.gz,.Z}/" "n/-n1/f:*.ndx{,.gz,.Z}/" "n/-n2/f:*.ndx{,.gz,.Z}/" "n/-no/f:*.ndx{,.gz,.Z}/" "c/-/( f1 f2 o n1 n2 no h version nice w one nomw pbc nofit name label bfac)/"
 complete g_covar "n/-tu/( fs ps ns us ms s)/" "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-v/f:*.{trr,cpt,trj}{,.gz,.Z}/" "n/-av/f:*.{gro,g96,pdb,brk,ent,esp,xyz}{,.gz,.Z}/" "n/-l/f:*.log{,.gz,.Z}/" "n/-ascii/f:*.dat{,.gz,.Z}/" "n/-xpm/f:*.xpm{,.gz,.Z}/" "n/-xpma/f:*.xpm{,.gz,.Z}/" "c/-/( f s n o v av l ascii xpm xpma h version nice b e dt tu xvg nofit ref mwa last nopbc)/"
 complete g_current "n/-xvg/( xmgrace xmgr none)/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-caf/f:*.xvg{,.gz,.Z}/" "n/-dsp/f:*.xvg{,.gz,.Z}/" "n/-md/f:*.xvg{,.gz,.Z}/" "n/-mj/f:*.xvg{,.gz,.Z}/" "n/-mc/f:*.xvg{,.gz,.Z}/" "c/-/( s n f o caf dsp md mj mc h version nice b e dt w xvg sh nonojump eps bfit efit bvit evit tr temp)/"
 complete g_density "n/-xvg/( xmgrace xmgr none)/" "n/-dens/( mass number charge electron)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-ei/f:*.dat{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "c/-/( f n s ei o h version nice b e dt w xvg d sl dens ng symm center)/"
 complete g_densmap "n/-aver/( z y x)/" "n/-unit/( nm-3 nm-2 count)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-od/f:*.dat{,.gz,.Z}/" "n/-o/f:*.xpm{,.gz,.Z}/" "c/-/( f s n od o h version nice b e dt w bin aver xmin xmax n1 n2 amax rmax mirror sums unit dmin dmax)/"
-complete g_dielectric "n/-xvg/( xmgrace xmgr none)/" "n/-ffn/( none exp aexp exp_exp vac exp5 exp7 exp9)/" "n/-f/f:*.xvg{,.gz,.Z}/" "n/-d/f:*.xvg{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-c/f:*.xvg{,.gz,.Z}/" "c/-/( f d o c h version nice b e dt w xvg fft nox1 eint bfit efit tail A tau1 tau2 eps0 epsRF fix ffn nsmooth)/"
-complete g_dih "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-o/f:*.out{,.gz,.Z}/" "c/-/( f s o h version nice b e dt w sa mult)/"
-complete g_dipoles "n/-xvg/( xmgrace xmgr none)/" "n/-corr/( none mol molsep total)/" "n/-P/( 0 1 2 3)/" "n/-fitfn/( none exp aexp exp_exp vac exp5 exp7 exp9)/" "n/-en/f:*.edr{,.gz,.Z}/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-eps/f:*.xvg{,.gz,.Z}/" "n/-a/f:*.xvg{,.gz,.Z}/" "n/-d/f:*.xvg{,.gz,.Z}/" "n/-c/f:*.xvg{,.gz,.Z}/" "n/-g/f:*.xvg{,.gz,.Z}/" "n/-adip/f:*.xvg{,.gz,.Z}/" "n/-dip3d/f:*.xvg{,.gz,.Z}/" "n/-cos/f:*.xvg{,.gz,.Z}/" "n/-cmap/f:*.xpm{,.gz,.Z}/" "n/-q/f:*.xvg{,.gz,.Z}/" "n/-slab/f:*.xvg{,.gz,.Z}/" "c/-/( en f s n o eps a d c g adip dip3d cos cmap q slab h version nice b e dt w xvg mu mumax epsilonRF skip temp corr nopairs ncos axis sl gkratom gkratom2 rcmax phi nlevels ndegrees acflen nonormalize P fitfn ncskip beginfit endfit)/"
+complete g_densorder "n/-method/( bisect functional)/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-o/f:*.dat{,.gz,.Z}/" "n/-or/f:*.out{,.gz,.Z}/" "n/-og/f:*.xpm{,.gz,.Z}/" "n/-Spect/f:*.out{,.gz,.Z}/" "c/-/( s f n o or og Spect h version nice b e dt w 1d bw bwn order axis method d1 d2 tblock nlevel)/"
+complete g_dielectric "n/-xvg/( xmgrace xmgr none)/" "n/-ffn/( none exp aexp exp_exp vac exp5 exp7 exp9 erffit)/" "n/-f/f:*.xvg{,.gz,.Z}/" "n/-d/f:*.xvg{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-c/f:*.xvg{,.gz,.Z}/" "c/-/( f d o c h version nice b e dt w xvg fft nox1 eint bfit efit tail A tau1 tau2 eps0 epsRF fix ffn nsmooth)/"
+complete g_dipoles "n/-xvg/( xmgrace xmgr none)/" "n/-corr/( none mol molsep total)/" "n/-P/( 0 1 2 3)/" "n/-fitfn/( none exp aexp exp_exp vac exp5 exp7 exp9 erffit)/" "n/-en/f:*.edr{,.gz,.Z}/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-eps/f:*.xvg{,.gz,.Z}/" "n/-a/f:*.xvg{,.gz,.Z}/" "n/-d/f:*.xvg{,.gz,.Z}/" "n/-c/f:*.xvg{,.gz,.Z}/" "n/-g/f:*.xvg{,.gz,.Z}/" "n/-adip/f:*.xvg{,.gz,.Z}/" "n/-dip3d/f:*.xvg{,.gz,.Z}/" "n/-cos/f:*.xvg{,.gz,.Z}/" "n/-cmap/f:*.xpm{,.gz,.Z}/" "n/-q/f:*.xvg{,.gz,.Z}/" "n/-slab/f:*.xvg{,.gz,.Z}/" "c/-/( en f s n o eps a d c g adip dip3d cos cmap q slab h version nice b e dt w xvg mu mumax epsilonRF skip temp corr nopairs ncos axis sl gkratom gkratom2 rcmax phi nlevels ndegrees acflen nonormalize P fitfn ncskip beginfit endfit)/"
 complete g_disre "n/-xvg/( xmgrace xmgr none)/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-ds/f:*.xvg{,.gz,.Z}/" "n/-da/f:*.xvg{,.gz,.Z}/" "n/-dn/f:*.xvg{,.gz,.Z}/" "n/-dm/f:*.xvg{,.gz,.Z}/" "n/-dr/f:*.xvg{,.gz,.Z}/" "n/-l/f:*.log{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-q/f:*.pdb{,.gz,.Z}/" "n/-c/f:*.ndx{,.gz,.Z}/" "n/-x/f:*.xpm{,.gz,.Z}/" "c/-/( s f ds da dn dm dr l n q c x h version nice b e dt w xvg ntop maxdr nlevels nothird)/"
-complete g_dist "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-lt/f:*.xvg{,.gz,.Z}/" "c/-/( f s n o lt h version nice b e dt xvg dist)/"
+complete g_dist "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-lt/f:*.xvg{,.gz,.Z}/" "c/-/( f s n o lt h version nice b e dt xvg intra dist)/"
+complete g_dos "n/-xvg/( xmgrace xmgr none)/" "n/-P/( 0 1 2 3)/" "n/-fitfn/( none exp aexp exp_exp vac exp5 exp7 exp9 erffit)/" "n/-f/f:*.{trr,cpt,trj}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-vacf/f:*.xvg{,.gz,.Z}/" "n/-mvacf/f:*.xvg{,.gz,.Z}/" "n/-dos/f:*.xvg{,.gz,.Z}/" "n/-g/f:*.log{,.gz,.Z}/" "c/-/( f s n vacf mvacf dos g h version nice b e dt w xvg nov recip abs normdos T acflen nonormalize P fitfn ncskip beginfit endfit)/"
+complete g_dyecoupl "n/-tu/( fs ps ns us ms s)/" "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-ot/f:*.xvg{,.gz,.Z}/" "n/-oe/f:*.xvg{,.gz,.Z}/" "n/-o/f:*.dat{,.gz,.Z}/" "n/-rhist/f:*.xvg{,.gz,.Z}/" "n/-khist/f:*.xvg{,.gz,.Z}/" "c/-/( f n ot oe o rhist khist h version nice b e tu w xvg pbcdist norm bins R0)/"
 complete g_dyndom "n/-f/f:*.pdb{,.gz,.Z}/" "n/-o/f:*.{xtc,trr,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "c/-/( f o n h version nice firstangle lastangle nframe maxangle trans head tail)/"
-complete g_enemat "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.edr{,.gz,.Z}/" "n/-groups/f:*.dat{,.gz,.Z}/" "n/-eref/f:*.dat{,.gz,.Z}/" "n/-emat/f:*.xpm{,.gz,.Z}/" "n/-etot/f:*.xvg{,.gz,.Z}/" "c/-/( f groups eref emat etot h version nice b e dt w xvg sum skip nomean nlevels max min nocoul coulr coul14 nolj lj lj14 bhamsr bhamlr nofree temp)/"
-complete g_energy "n/-xvg/( xmgrace xmgr none)/" "n/-P/( 0 1 2 3)/" "n/-fitfn/( none exp aexp exp_exp vac exp5 exp7 exp9)/" "n/-f/f:*.edr{,.gz,.Z}/" "n/-f2/f:*.edr{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-viol/f:*.xvg{,.gz,.Z}/" "n/-pairs/f:*.xvg{,.gz,.Z}/" "n/-ora/f:*.xvg{,.gz,.Z}/" "n/-ort/f:*.xvg{,.gz,.Z}/" "n/-oda/f:*.xvg{,.gz,.Z}/" "n/-odr/f:*.xvg{,.gz,.Z}/" "n/-odt/f:*.xvg{,.gz,.Z}/" "n/-oten/f:*.xvg{,.gz,.Z}/" "n/-corr/f:*.xvg{,.gz,.Z}/" "n/-vis/f:*.xvg{,.gz,.Z}/" "n/-ravg/f:*.xvg{,.gz,.Z}/" "c/-/( f f2 s o viol pairs ora ort oda odr odt oten corr vis ravg h version nice b e w xvg fee fetemp zero sum dp nbmin nbmax mutot skip aver nmol nconstr fluc orinst ovec acflen nonormalize P fitfn ncskip beginfit endfit)/"
+complete genbox "n/-cp/f:*.{gro,g96,pdb,brk,ent,esp,xyz,tpr,tpb,tpa}{,.gz,.Z}/" "n/-cs/f:*.{gro,g96,pdb,brk,ent,esp,xyz,tpr,tpb,tpa}{,.gz,.Z}/" "n/-ci/f:*.{gro,g96,pdb,brk,ent,esp,xyz,tpr,tpb,tpa}{,.gz,.Z}/" "n/-o/f:*.{gro,g96,pdb,brk,ent,esp,xyz}{,.gz,.Z}/" "n/-p/f:*.top{,.gz,.Z}/" "c/-/( cp cs ci o p h version nice box nmol try seed vdwd shell maxsol vel)/"
+complete genconf "n/-f/f:*.{gro,g96,pdb,brk,ent,esp,xyz,tpr,tpb,tpa}{,.gz,.Z}/" "n/-o/f:*.{gro,g96,pdb,brk,ent,esp,xyz}{,.gz,.Z}/" "n/-trj/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "c/-/( f o trj h version nice nbox dist seed rot shuffle sort block nmolat maxrot norenumber)/"
+complete g_enemat "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.edr{,.gz,.Z}/" "n/-groups/f:*.dat{,.gz,.Z}/" "n/-eref/f:*.dat{,.gz,.Z}/" "n/-emat/f:*.xpm{,.gz,.Z}/" "n/-etot/f:*.xvg{,.gz,.Z}/" "c/-/( f groups eref emat etot h version nice b e dt w xvg sum skip nomean nlevels max min nocoulsr coullr coul14 noljsr ljlr lj14 bhamsr bhamlr nofree temp)/"
+complete g_energy "n/-xvg/( xmgrace xmgr none)/" "n/-P/( 0 1 2 3)/" "n/-fitfn/( none exp aexp exp_exp vac exp5 exp7 exp9 erffit)/" "n/-f/f:*.edr{,.gz,.Z}/" "n/-f2/f:*.edr{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-viol/f:*.xvg{,.gz,.Z}/" "n/-pairs/f:*.xvg{,.gz,.Z}/" "n/-ora/f:*.xvg{,.gz,.Z}/" "n/-ort/f:*.xvg{,.gz,.Z}/" "n/-oda/f:*.xvg{,.gz,.Z}/" "n/-odr/f:*.xvg{,.gz,.Z}/" "n/-odt/f:*.xvg{,.gz,.Z}/" "n/-oten/f:*.xvg{,.gz,.Z}/" "n/-corr/f:*.xvg{,.gz,.Z}/" "n/-vis/f:*.xvg{,.gz,.Z}/" "n/-ravg/f:*.xvg{,.gz,.Z}/" "n/-odh/f:*.xvg{,.gz,.Z}/" "c/-/( f f2 s o viol pairs ora ort oda odr odt oten corr vis ravg odh h version nice b e w xvg fee fetemp zero sum dp nbmin nbmax mutot skip aver nmol fluct_props driftcorr fluc orinst ovec acflen nonormalize P fitfn ncskip beginfit endfit)/"
+complete genion "n/-xvg/( xmgrace xmgr none)/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-table/f:*.xvg{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-o/f:*.{gro,g96,pdb,brk,ent,esp,xyz}{,.gz,.Z}/" "n/-g/f:*.log{,.gz,.Z}/" "n/-pot/f:*.pdb{,.gz,.Z}/" "n/-p/f:*.top{,.gz,.Z}/" "c/-/( s table n o g pot p h version nice xvg np pname pq nn nname nq rmin norandom seed scale conc neutral)/"
+complete genrestr "n/-f/f:*.{gro,g96,pdb,brk,ent,esp,xyz,tpr,tpb,tpa}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-o/f:*.itp{,.gz,.Z}/" "n/-of/f:*.ndx{,.gz,.Z}/" "c/-/( f n o of h version nice fc freeze disre disre_dist disre_frac disre_up2 cutoff constr)/"
 complete g_filter "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-ol/f:*.{xtc,trr,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-oh/f:*.{xtc,trr,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "c/-/( f s n ol oh h version nice b e dt w nf all nonojump fit)/"
-complete g_gyrate "n/-xvg/( xmgrace xmgr none)/" "n/-P/( 0 1 2 3)/" "n/-fitfn/( none exp aexp exp_exp vac exp5 exp7 exp9)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-acf/f:*.xvg{,.gz,.Z}/" "c/-/( f s n o acf h version nice b e dt w xvg nmol q p moi nz acflen nonormalize P fitfn ncskip beginfit endfit)/"
+complete g_gyrate "n/-xvg/( xmgrace xmgr none)/" "n/-P/( 0 1 2 3)/" "n/-fitfn/( none exp aexp exp_exp vac exp5 exp7 exp9 erffit)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-acf/f:*.xvg{,.gz,.Z}/" "c/-/( f s n o acf h version nice b e dt w xvg nmol q p moi nz acflen nonormalize P fitfn ncskip beginfit endfit)/"
 complete g_h2order "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-nm/f:*.ndx{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "c/-/( f n nm s o h version nice b e dt w xvg d sl)/"
-complete g_hbond "n/-xvg/( xmgrace xmgr none)/" "n/-geminate/( none dd ad aa a4)/" "n/-P/( 0 1 2 3)/" "n/-fitfn/( none exp aexp exp_exp vac exp5 exp7 exp9)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-num/f:*.xvg{,.gz,.Z}/" "n/-g/f:*.log{,.gz,.Z}/" "n/-ac/f:*.xvg{,.gz,.Z}/" "n/-dist/f:*.xvg{,.gz,.Z}/" "n/-ang/f:*.xvg{,.gz,.Z}/" "n/-hx/f:*.xvg{,.gz,.Z}/" "n/-hbn/f:*.ndx{,.gz,.Z}/" "n/-hbm/f:*.xpm{,.gz,.Z}/" "n/-don/f:*.xvg{,.gz,.Z}/" "n/-dan/f:*.xvg{,.gz,.Z}/" "n/-life/f:*.xvg{,.gz,.Z}/" "n/-nhbdist/f:*.xvg{,.gz,.Z}/" "c/-/( f s n num g ac dist ang hx hbn hbm don dan life nhbdist h version nice b e dt xvg a r noda r2 abin rbin nonitacc contact shell fitstart fitstart temp smooth dump max_hb nomerge geminate diff acflen nonormalize P fitfn ncskip beginfit endfit)/"
+complete g_hbond "n/-tu/( fs ps ns us ms s)/" "n/-xvg/( xmgrace xmgr none)/" "n/-geminate/( none dd ad aa a4)/" "n/-P/( 0 1 2 3)/" "n/-fitfn/( none exp aexp exp_exp vac exp5 exp7 exp9 erffit)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-num/f:*.xvg{,.gz,.Z}/" "n/-g/f:*.log{,.gz,.Z}/" "n/-ac/f:*.xvg{,.gz,.Z}/" "n/-dist/f:*.xvg{,.gz,.Z}/" "n/-ang/f:*.xvg{,.gz,.Z}/" "n/-hx/f:*.xvg{,.gz,.Z}/" "n/-hbn/f:*.ndx{,.gz,.Z}/" "n/-hbm/f:*.xpm{,.gz,.Z}/" "n/-don/f:*.xvg{,.gz,.Z}/" "n/-dan/f:*.xvg{,.gz,.Z}/" "n/-life/f:*.xvg{,.gz,.Z}/" "n/-nhbdist/f:*.xvg{,.gz,.Z}/" "c/-/( f s n num g ac dist ang hx hbn hbm don dan life nhbdist h version nice b e dt tu xvg a r noda r2 abin rbin nonitacc contact shell fitstart fitstart temp smooth dump max_hb nomerge geminate diff acflen nonormalize P fitfn ncskip beginfit endfit)/"
 complete g_helix "n/-prop/( RAD TWIST RISE LEN NHX DIP RMS CPHI RMSA PHI PSI HB3 HB4 HB5 CD222)/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-to/f:*.g87{,.gz,.Z}/" "n/-cz/f:*.{gro,g96,pdb,brk,ent,esp,xyz}{,.gz,.Z}/" "n/-co/f:*.{gro,g96,pdb,brk,ent,esp,xyz}{,.gz,.Z}/" "c/-/( s n f to cz co h version nice b e dt w r0 q noF db prop ev ahxstart ahxend)/"
 complete g_helixorient "n/-xvg/( xmgrace xmgr none)/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-oaxis/f:*.dat{,.gz,.Z}/" "n/-ocenter/f:*.dat{,.gz,.Z}/" "n/-orise/f:*.xvg{,.gz,.Z}/" "n/-oradius/f:*.xvg{,.gz,.Z}/" "n/-otwist/f:*.xvg{,.gz,.Z}/" "n/-obending/f:*.xvg{,.gz,.Z}/" "n/-otilt/f:*.xvg{,.gz,.Z}/" "n/-orot/f:*.xvg{,.gz,.Z}/" "c/-/( s f n oaxis ocenter orise oradius otwist obending otilt orot h version nice b e dt xvg sidechain incremental)/"
+complete g_hydorder "n/-d/( z x y)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-o/f:*.xpm{,.gz,.Z}/" "n/-or/f:*.out{,.gz,.Z}/" "n/-Spect/f:*.out{,.gz,.Z}/" "c/-/( f n s o or Spect h version nice b e dt w d bw sgang1 sgang2 tblock nlevel)/"
+complete g_kinetics "n/-tu/( fs ps ns us ms s)/" "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.xvg{,.gz,.Z}/" "n/-d/f:*.xvg{,.gz,.Z}/" "n/-d2/f:*.xvg{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-o2/f:*.xvg{,.gz,.Z}/" "n/-o3/f:*.xvg{,.gz,.Z}/" "n/-ee/f:*.xvg{,.gz,.Z}/" "n/-g/f:*.log{,.gz,.Z}/" "n/-m/f:*.xvg{,.gz,.Z}/" "c/-/( f d d2 o o2 o3 ee g m h version nice tu w xvg notime b e bfit efit T n cut ucut euf efu ei maxiter noback tol skip nosplit nosum nodiscrete mult)/"
 complete g_lie "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.edr{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "c/-/( f o h version nice b e dt w xvg Elj Eqq Clj Cqq ligand)/"
 complete g_mdmat "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-mean/f:*.xpm{,.gz,.Z}/" "n/-frames/f:*.xpm{,.gz,.Z}/" "n/-no/f:*.xvg{,.gz,.Z}/" "c/-/( f s n mean frames no h version nice b e dt xvg t nlevels)/"
-complete g_membed "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-p/f:*.top{,.gz,.Z}/" "n/-o/f:*.{trr,cpt,trj}{,.gz,.Z}/" "n/-x/f:*.xtc{,.gz,.Z}/" "n/-cpi/f:*.cpt{,.gz,.Z}/" "n/-cpo/f:*.cpt{,.gz,.Z}/" "n/-c/f:*.{gro,g96,pdb,brk,ent,esp,xyz}{,.gz,.Z}/" "n/-e/f:*.edr{,.gz,.Z}/" "n/-g/f:*.log{,.gz,.Z}/" "n/-ei/f:*.edi{,.gz,.Z}/" "n/-rerun/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-table/f:*.xvg{,.gz,.Z}/" "n/-tablep/f:*.xvg{,.gz,.Z}/" "n/-tableb/f:*.xvg{,.gz,.Z}/" "n/-dhdl/f:*.xvg{,.gz,.Z}/" "n/-field/f:*.xvg{,.gz,.Z}/" "n/-table/f:*.xvg{,.gz,.Z}/" "n/-tablep/f:*.xvg{,.gz,.Z}/" "n/-tableb/f:*.xvg{,.gz,.Z}/" "n/-rerun/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-tpi/f:*.xvg{,.gz,.Z}/" "n/-tpid/f:*.xvg{,.gz,.Z}/" "n/-ei/f:*.edi{,.gz,.Z}/" "n/-eo/f:*.edo{,.gz,.Z}/" "n/-j/f:*.gct{,.gz,.Z}/" "n/-jo/f:*.gct{,.gz,.Z}/" "n/-ffout/f:*.xvg{,.gz,.Z}/" "n/-devout/f:*.xvg{,.gz,.Z}/" "n/-runav/f:*.xvg{,.gz,.Z}/" "n/-px/f:*.xvg{,.gz,.Z}/" "n/-pf/f:*.xvg{,.gz,.Z}/" "n/-mtx/f:*.mtx{,.gz,.Z}/" "n/-dn/f:*.ndx{,.gz,.Z}/" "c/-/( f n p o x cpi cpo c e g ei rerun table tablep tableb dhdl field table tablep tableb rerun tpi tpid ei eo j jo ffout devout runav px pf mtx dn h version nice deffnm xvg xyinit xyend zinit zend nxy nz rad pieces asymmetry ndiff maxwarn nocompact v)/"
+complete g_membed "n/-f/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-p/f:*.top{,.gz,.Z}/" "n/-o/f:*.{trr,cpt,trj}{,.gz,.Z}/" "n/-x/f:*.xtc{,.gz,.Z}/" "n/-c/f:*.{gro,g96,pdb,brk,ent,esp,xyz}{,.gz,.Z}/" "n/-e/f:*.edr{,.gz,.Z}/" "n/-dat/f:*.dat{,.gz,.Z}/" "c/-/( f n p o x c e dat h version nice xyinit xyend zinit zend nxy nz rad pieces asymmetry ndiff maxwarn start v mdrun_path)/"
 complete g_mindist "n/-tu/( fs ps ns us ms s)/" "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-od/f:*.xvg{,.gz,.Z}/" "n/-on/f:*.xvg{,.gz,.Z}/" "n/-o/f:*.out{,.gz,.Z}/" "n/-ox/f:*.{xtc,trr,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-or/f:*.xvg{,.gz,.Z}/" "c/-/( f s n od on o ox or h version nice b e dt tu w xvg matrix max d group pi split ng nopbc respertime printresname)/"
 complete g_morph "n/-xvg/( xmgrace xmgr none)/" "n/-f1/f:*.{gro,g96,pdb,brk,ent,esp,xyz,tpr,tpb,tpa}{,.gz,.Z}/" "n/-f2/f:*.{gro,g96,pdb,brk,ent,esp,xyz,tpr,tpb,tpa}{,.gz,.Z}/" "n/-o/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-or/f:*.xvg{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "c/-/( f1 f2 o or n h version nice w xvg ninterm first last nofit)/"
 complete g_msd "n/-tu/( fs ps ns us ms s)/" "n/-xvg/( xmgrace xmgr none)/" "n/-type/( no x y z)/" "n/-lateral/( no x y z)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-mol/f:*.xvg{,.gz,.Z}/" "n/-pdb/f:*.pdb{,.gz,.Z}/" "c/-/( f s n o mol pdb h version nice b e tu w xvg type lateral ten ngroup nomw rmcomm tpdb trestart beginfit endfit)/"
-complete g_nmeig "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.mtx{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-of/f:*.xvg{,.gz,.Z}/" "n/-ol/f:*.xvg{,.gz,.Z}/" "n/-v/f:*.{trr,cpt,trj}{,.gz,.Z}/" "c/-/( f s of ol v h version nice xvg nom first last)/"
+complete gmxcheck "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-f2/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s1/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-s2/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-c/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-e/f:*.edr{,.gz,.Z}/" "n/-e2/f:*.edr{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-m/f:*.tex{,.gz,.Z}/" "c/-/( f f2 s1 s2 c e e2 n m h version nice vdwfac bonlo bonhi rmsd tol abstol ab lastener)/"
+complete gmxdump "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-e/f:*.edr{,.gz,.Z}/" "n/-cp/f:*.cpt{,.gz,.Z}/" "n/-p/f:*.top{,.gz,.Z}/" "n/-mtx/f:*.mtx{,.gz,.Z}/" "n/-om/f:*.mdp{,.gz,.Z}/" "c/-/( s f e cp p mtx om h version nice nonr sys)/"
+complete g_nmeig "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.mtx{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-of/f:*.xvg{,.gz,.Z}/" "n/-ol/f:*.xvg{,.gz,.Z}/" "n/-os/f:*.xvg{,.gz,.Z}/" "n/-qc/f:*.xvg{,.gz,.Z}/" "n/-v/f:*.{trr,cpt,trj}{,.gz,.Z}/" "c/-/( f s of ol os qc v h version nice xvg nom first last maxspec T constr width)/"
 complete g_nmens "n/-xvg/( xmgrace xmgr none)/" "n/-v/f:*.{trr,cpt,trj}{,.gz,.Z}/" "n/-e/f:*.xvg{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-o/f:*.{xtc,trr,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "c/-/( v e s n o h version nice xvg temp seed num first last)/"
 complete g_nmtraj "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-v/f:*.{trr,cpt,trj}{,.gz,.Z}/" "n/-o/f:*.{xtc,trr,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "c/-/( s v o h version nice eignr phases temp amplitude nframes)/"
+complete g_options "c/-/( h version nice)/"
 complete g_order "n/-xvg/( xmgrace xmgr none)/" "n/-d/( z x y)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-nr/f:*.ndx{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-od/f:*.xvg{,.gz,.Z}/" "n/-ob/f:*.pdb{,.gz,.Z}/" "n/-os/f:*.xvg{,.gz,.Z}/" "n/-Sg/f:*.xvg{,.gz,.Z}/" "n/-Sk/f:*.xvg{,.gz,.Z}/" "n/-Sgsl/f:*.xvg{,.gz,.Z}/" "n/-Sksl/f:*.xvg{,.gz,.Z}/" "c/-/( f n nr s o od ob os Sg Sk Sgsl Sksl h version nice b e dt w xvg d sl szonly unsat permolecule radial calcdist)/"
+complete g_pme_error "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-o/f:*.out{,.gz,.Z}/" "n/-so/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "c/-/( s o so h version nice beta tune self seed v)/"
 complete g_polystat "n/-tu/( fs ps ns us ms s)/" "n/-xvg/( xmgrace xmgr none)/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-v/f:*.xvg{,.gz,.Z}/" "n/-p/f:*.xvg{,.gz,.Z}/" "n/-i/f:*.xvg{,.gz,.Z}/" "c/-/( s f n o v p i h version nice b e dt tu w xvg nomw pc)/"
 complete g_potential "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-oc/f:*.xvg{,.gz,.Z}/" "n/-of/f:*.xvg{,.gz,.Z}/" "c/-/( f n s o oc of h version nice b e dt w xvg d sl cb ce tz spherical ng correct)/"
 complete g_principal "n/-tu/( fs ps ns us ms s)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-a1/f:*.dat{,.gz,.Z}/" "n/-a2/f:*.dat{,.gz,.Z}/" "n/-a3/f:*.dat{,.gz,.Z}/" "n/-om/f:*.dat{,.gz,.Z}/" "c/-/( f s n a1 a2 a3 om h version nice b e dt tu w foo)/"
@@ -49,11 +61,12 @@ complete g_rdf "n/-xvg/( xmgrace xmgr none)/" "n/-surf/( no mol res)/" "n/-rdf/(
 complete g_rms "n/-tu/( fs ps ns us ms s)/" "n/-xvg/( xmgrace xmgr none)/" "n/-what/( rmsd rho rhosc)/" "n/-fit/( rot+trans translation none)/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-f2/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-mir/f:*.xvg{,.gz,.Z}/" "n/-a/f:*.xvg{,.gz,.Z}/" "n/-dist/f:*.xvg{,.gz,.Z}/" "n/-m/f:*.xpm{,.gz,.Z}/" "n/-bin/f:*.dat{,.gz,.Z}/" "n/-bm/f:*.xpm{,.gz,.Z}/" "c/-/( s f f2 n o mir a dist m bin bm h version nice b e dt tu w xvg what nopbc fit prev split skip skip2 max min bmax bmin nomw nlevels ng)/"
 complete g_rmsdist "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-equiv/f:*.dat{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-rms/f:*.xpm{,.gz,.Z}/" "n/-scl/f:*.xpm{,.gz,.Z}/" "n/-mean/f:*.xpm{,.gz,.Z}/" "n/-nmr3/f:*.xpm{,.gz,.Z}/" "n/-nmr6/f:*.xpm{,.gz,.Z}/" "n/-noe/f:*.dat{,.gz,.Z}/" "c/-/( f s n equiv o rms scl mean nmr3 nmr6 noe h version nice b e dt w xvg nlevels max nosumh nopbc)/"
 complete g_rmsf "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-q/f:*.pdb{,.gz,.Z}/" "n/-oq/f:*.pdb{,.gz,.Z}/" "n/-ox/f:*.pdb{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-od/f:*.xvg{,.gz,.Z}/" "n/-oc/f:*.xvg{,.gz,.Z}/" "n/-dir/f:*.log{,.gz,.Z}/" "c/-/( f s n q oq ox o od oc dir h version nice b e dt w xvg res aniso nofit)/"
-complete g_rotacf "n/-xvg/( xmgrace xmgr none)/" "n/-P/( 0 1 2 3)/" "n/-fitfn/( none exp aexp exp_exp vac exp5 exp7 exp9)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "c/-/( f s n o h version nice b e dt w xvg d noaver acflen nonormalize P fitfn ncskip beginfit endfit)/"
+complete grompp "n/-f/f:*.mdp{,.gz,.Z}/" "n/-po/f:*.mdp{,.gz,.Z}/" "n/-c/f:*.{gro,g96,pdb,brk,ent,esp,xyz,tpr,tpb,tpa}{,.gz,.Z}/" "n/-r/f:*.{gro,g96,pdb,brk,ent,esp,xyz,tpr,tpb,tpa}{,.gz,.Z}/" "n/-rb/f:*.{gro,g96,pdb,brk,ent,esp,xyz,tpr,tpb,tpa}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-p/f:*.top{,.gz,.Z}/" "n/-pp/f:*.top{,.gz,.Z}/" "n/-o/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-t/f:*.{trr,cpt,trj}{,.gz,.Z}/" "n/-e/f:*.edr{,.gz,.Z}/" "n/-ref/f:*.{trr,cpt,trj}{,.gz,.Z}/" "c/-/( f po c r rb n p pp o t e ref h version nice v time normvsbds maxwarn zero norenum)/"
+complete g_rotacf "n/-xvg/( xmgrace xmgr none)/" "n/-P/( 0 1 2 3)/" "n/-fitfn/( none exp aexp exp_exp vac exp5 exp7 exp9 erffit)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "c/-/( f s n o h version nice b e dt w xvg d noaver acflen nonormalize P fitfn ncskip beginfit endfit)/"
 complete g_rotmat "n/-xvg/( xmgrace xmgr none)/" "n/-ref/( none xyz xy)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "c/-/( f s n o h version nice b e dt w xvg ref skip fitxy nomw)/"
 complete g_saltbr "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "c/-/( f s h version nice b e dt t sep)/"
+complete g_sans "n/-tu/( fs ps ns us ms s)/" "n/-xvg/( xmgrace xmgr none)/" "n/-mode/( direct mc)/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-d/f:*.dat{,.gz,.Z}/" "n/-pr/f:*.xvg{,.gz,.Z}/" "n/-sq/f:*.xvg{,.gz,.Z}/" "n/-prframe/f:*.xvg{,.gz,.Z}/" "n/-sqframe/f:*.xvg{,.gz,.Z}/" "c/-/( s f n d pr sq prframe sqframe h version nice b e dt tu xvg mode mcover nopbc startq endq qstep seed)/"
 complete g_sas "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-or/f:*.xvg{,.gz,.Z}/" "n/-oa/f:*.xvg{,.gz,.Z}/" "n/-tv/f:*.xvg{,.gz,.Z}/" "n/-q/f:*.pdb{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-i/f:*.itp{,.gz,.Z}/" "c/-/( f s o or oa tv q n i h version nice b e dt w xvg probe ndots qmax f_index minarea nopbc noprot dgs)/"
-complete g_sdf "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-o/f:*.dat{,.gz,.Z}/" "n/-r/f:*.{gro,g96,pdb,brk,ent,esp,xyz}{,.gz,.Z}/" "c/-/( f n s o r h version nice b e dt mode triangle dtri bin grid)/"
 complete g_select "n/-xvg/( xmgrace xmgr none)/" "n/-selrpos/( atom res_com res_cog mol_com mol_cog whole_res_com whole_res_cog whole_mol_com whole_mol_cog part_res_com part_res_cog part_mol_com part_mol_cog dyn_res_com dyn_res_cog dyn_mol_com dyn_mol_cog)/" "n/-seltype/( atom res_com res_cog mol_com mol_cog whole_res_com whole_res_cog whole_mol_com whole_mol_cog part_res_com part_res_cog part_mol_com part_mol_cog dyn_res_com dyn_res_cog dyn_mol_com dyn_mol_cog)/" "n/-resnr/( number index)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-sf/f:*.dat{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-os/f:*.xvg{,.gz,.Z}/" "n/-oc/f:*.xvg{,.gz,.Z}/" "n/-oi/f:*.dat{,.gz,.Z}/" "n/-om/f:*.dat{,.gz,.Z}/" "n/-on/f:*.ndx{,.gz,.Z}/" "c/-/( f s sf n os oc oi om on h version nice b e dt xvg normpbc nopbc select selrpos seltype dump norm cfnorm resnr)/"
 complete g_sgangle "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-oa/f:*.xvg{,.gz,.Z}/" "n/-od/f:*.xvg{,.gz,.Z}/" "n/-od1/f:*.xvg{,.gz,.Z}/" "n/-od2/f:*.xvg{,.gz,.Z}/" "c/-/( f n s oa od od1 od2 h version nice b e dt w xvg one z)/"
 complete g_sham "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.xvg{,.gz,.Z}/" "n/-ge/f:*.xvg{,.gz,.Z}/" "n/-ene/f:*.xvg{,.gz,.Z}/" "n/-dist/f:*.xvg{,.gz,.Z}/" "n/-histo/f:*.xvg{,.gz,.Z}/" "n/-bin/f:*.ndx{,.gz,.Z}/" "n/-lp/f:*.xpm{,.gz,.Z}/" "n/-ls/f:*.xpm{,.gz,.Z}/" "n/-lsh/f:*.xpm{,.gz,.Z}/" "n/-lss/f:*.xpm{,.gz,.Z}/" "n/-map/f:*.xpm{,.gz,.Z}/" "n/-ls3/f:*.pdb{,.gz,.Z}/" "n/-mdata/f:*.xvg{,.gz,.Z}/" "n/-g/f:*.log{,.gz,.Z}/" "c/-/( f ge ene dist histo bin lp ls lsh lss map ls3 mdata g h version nice w xvg notime b e ttol n d bw nosham tsham pmin dim ngrid xmin xmax pmax gmax emin emax nlevels mname)/"
@@ -61,30 +74,24 @@ complete g_sigeps "n/-xvg/( xmgrace xmgr none)/" "n/-o/f:*.xvg{,.gz,.Z}/" "c/-/(
 complete g_sorient "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-no/f:*.xvg{,.gz,.Z}/" "n/-ro/f:*.xvg{,.gz,.Z}/" "n/-co/f:*.xvg{,.gz,.Z}/" "n/-rc/f:*.xvg{,.gz,.Z}/" "c/-/( f s n o no ro co rc h version nice b e dt w xvg com v23 rmin rmax cbin rbin pbc)/"
 complete g_spatial "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "c/-/( s f n h version nice b e dt w pbc nodiv ign bin nab)/"
 complete g_spol "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "c/-/( f s n o h version nice b e dt w xvg com refat rmin rmax dip bw)/"
-complete g_tcaf "n/-xvg/( xmgrace xmgr none)/" "n/-P/( 0 1 2 3)/" "n/-fitfn/( none exp aexp exp_exp vac exp5 exp7 exp9)/" "n/-f/f:*.{trr,cpt,trj}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-ot/f:*.xvg{,.gz,.Z}/" "n/-oa/f:*.xvg{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-of/f:*.xvg{,.gz,.Z}/" "n/-oc/f:*.xvg{,.gz,.Z}/" "n/-ov/f:*.xvg{,.gz,.Z}/" "c/-/( f s n ot oa o of oc ov h version nice b e dt w xvg mol k34 wt acflen nonormalize P fitfn ncskip beginfit endfit)/"
-complete g_traj "n/-tu/( fs ps ns us ms s)/" "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-ox/f:*.xvg{,.gz,.Z}/" "n/-oxt/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-ov/f:*.xvg{,.gz,.Z}/" "n/-of/f:*.xvg{,.gz,.Z}/" "n/-ob/f:*.xvg{,.gz,.Z}/" "n/-ot/f:*.xvg{,.gz,.Z}/" "n/-ekt/f:*.xvg{,.gz,.Z}/" "n/-ekr/f:*.xvg{,.gz,.Z}/" "n/-vd/f:*.xvg{,.gz,.Z}/" "n/-cv/f:*.pdb{,.gz,.Z}/" "n/-cf/f:*.pdb{,.gz,.Z}/" "n/-av/f:*.xvg{,.gz,.Z}/" "n/-af/f:*.xvg{,.gz,.Z}/" "c/-/( f s n ox oxt ov of ob ot ekt ekr vd cv cf av af h version nice b e dt tu w xvg com nopbc mol nojump nox noy noz ng len fp bin scale)/"
-complete g_tune_pme "n/-xvg/( xmgrace xmgr none)/" "n/-npstring/( -np -n none)/" "n/-npme/( auto all subset)/" "n/-ddorder/( interleave pp_pme cartesian)/" "n/-dlb/( auto no yes)/" "n/-p/f:*.out{,.gz,.Z}/" "n/-err/f:*.log{,.gz,.Z}/" "n/-so/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-o/f:*.{trr,cpt,trj}{,.gz,.Z}/" "n/-x/f:*.xtc{,.gz,.Z}/" "n/-cpi/f:*.cpt{,.gz,.Z}/" "n/-cpo/f:*.cpt{,.gz,.Z}/" "n/-c/f:*.{gro,g96,pdb,brk,ent,esp,xyz}{,.gz,.Z}/" "n/-e/f:*.edr{,.gz,.Z}/" "n/-g/f:*.log{,.gz,.Z}/" "n/-dhdl/f:*.xvg{,.gz,.Z}/" "n/-field/f:*.xvg{,.gz,.Z}/" "n/-table/f:*.xvg{,.gz,.Z}/" "n/-tablep/f:*.xvg{,.gz,.Z}/" "n/-tableb/f:*.xvg{,.gz,.Z}/" "n/-rerun/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-tpi/f:*.xvg{,.gz,.Z}/" "n/-tpid/f:*.xvg{,.gz,.Z}/" "n/-ei/f:*.edi{,.gz,.Z}/" "n/-eo/f:*.edo{,.gz,.Z}/" "n/-j/f:*.gct{,.gz,.Z}/" "n/-jo/f:*.gct{,.gz,.Z}/" "n/-ffout/f:*.xvg{,.gz,.Z}/" "n/-devout/f:*.xvg{,.gz,.Z}/" "n/-runav/f:*.xvg{,.gz,.Z}/" "n/-px/f:*.xvg{,.gz,.Z}/" "n/-pf/f:*.xvg{,.gz,.Z}/" "n/-mtx/f:*.mtx{,.gz,.Z}/" "n/-dn/f:*.ndx{,.gz,.Z}/" "n/-bo/f:*.{trr,cpt,trj}{,.gz,.Z}/" "n/-bx/f:*.xtc{,.gz,.Z}/" "n/-bcpo/f:*.cpt{,.gz,.Z}/" "n/-bc/f:*.{gro,g96,pdb,brk,ent,esp,xyz}{,.gz,.Z}/" "n/-be/f:*.edr{,.gz,.Z}/" "n/-bg/f:*.log{,.gz,.Z}/" "n/-beo/f:*.edo{,.gz,.Z}/" "n/-bdhdl/f:*.xvg{,.gz,.Z}/" "n/-bfield/f:*.xvg{,.gz,.Z}/" "n/-btpi/f:*.xvg{,.gz,.Z}/" "n/-btpid/f:*.xvg{,.gz,.Z}/" "n/-bjo/f:*.gct{,.gz,.Z}/" "n/-bffout/f:*.xvg{,.gz,.Z}/" "n/-bdevout/f:*.xvg{,.gz,.Z}/" "n/-brunav/f:*.xvg{,.gz,.Z}/" "n/-bpx/f:*.xvg{,.gz,.Z}/" "n/-bpf/f:*.xvg{,.gz,.Z}/" "n/-bmtx/f:*.mtx{,.gz,.Z}/" "n/-bdn/f:*.ndx{,.gz,.Z}/" "c/-/( p err so s o x cpi cpo c e g dhdl field table tablep tableb rerun tpi tpid ei eo j jo ffout devout runav px pf mtx dn bo bx bcpo bc be bg beo bdhdl bfield btpi btpid bjo bffout bdevout brunav bpx bpf bmtx bdn h version nice xvg np npstring nt r max min npme upfac downfac ntpr four steps resetstep simsteps launch deffnm ddorder noddcheck rdd rcon dlb dds gcom v nocompact seppot pforce reprod cpt cpnum noappend maxh multi replex reseed ionize)/"
+complete g_tcaf "n/-xvg/( xmgrace xmgr none)/" "n/-P/( 0 1 2 3)/" "n/-fitfn/( none exp aexp exp_exp vac exp5 exp7 exp9 erffit)/" "n/-f/f:*.{trr,cpt,trj}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-ot/f:*.xvg{,.gz,.Z}/" "n/-oa/f:*.xvg{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-of/f:*.xvg{,.gz,.Z}/" "n/-oc/f:*.xvg{,.gz,.Z}/" "n/-ov/f:*.xvg{,.gz,.Z}/" "c/-/( f s n ot oa o of oc ov h version nice b e dt w xvg mol k34 wt acflen nonormalize P fitfn ncskip beginfit endfit)/"
+complete g_traj "n/-tu/( fs ps ns us ms s)/" "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-ox/f:*.xvg{,.gz,.Z}/" "n/-oxt/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-ov/f:*.xvg{,.gz,.Z}/" "n/-of/f:*.xvg{,.gz,.Z}/" "n/-ob/f:*.xvg{,.gz,.Z}/" "n/-ot/f:*.xvg{,.gz,.Z}/" "n/-ekt/f:*.xvg{,.gz,.Z}/" "n/-ekr/f:*.xvg{,.gz,.Z}/" "n/-vd/f:*.xvg{,.gz,.Z}/" "n/-cv/f:*.pdb{,.gz,.Z}/" "n/-cf/f:*.pdb{,.gz,.Z}/" "n/-av/f:*.xvg{,.gz,.Z}/" "n/-af/f:*.xvg{,.gz,.Z}/" "c/-/( f s n ox oxt ov of ob ot ekt ekr vd cv cf av af h version nice b e dt tu w xvg com nopbc mol nojump nox noy noz ng len fp bin ctime scale)/"
+complete g_tune_pme "n/-xvg/( xmgrace xmgr none)/" "n/-npstring/( -np -n none)/" "n/-npme/( auto all subset)/" "n/-p/f:*.out{,.gz,.Z}/" "n/-err/f:*.log{,.gz,.Z}/" "n/-so/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-o/f:*.{trr,cpt,trj}{,.gz,.Z}/" "n/-x/f:*.xtc{,.gz,.Z}/" "n/-cpi/f:*.cpt{,.gz,.Z}/" "n/-cpo/f:*.cpt{,.gz,.Z}/" "n/-c/f:*.{gro,g96,pdb,brk,ent,esp,xyz}{,.gz,.Z}/" "n/-e/f:*.edr{,.gz,.Z}/" "n/-g/f:*.log{,.gz,.Z}/" "n/-dhdl/f:*.xvg{,.gz,.Z}/" "n/-field/f:*.xvg{,.gz,.Z}/" "n/-table/f:*.xvg{,.gz,.Z}/" "n/-tabletf/f:*.xvg{,.gz,.Z}/" "n/-tablep/f:*.xvg{,.gz,.Z}/" "n/-tableb/f:*.xvg{,.gz,.Z}/" "n/-rerun/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-tpi/f:*.xvg{,.gz,.Z}/" "n/-tpid/f:*.xvg{,.gz,.Z}/" "n/-ei/f:*.edi{,.gz,.Z}/" "n/-eo/f:*.xvg{,.gz,.Z}/" "n/-j/f:*.gct{,.gz,.Z}/" "n/-jo/f:*.gct{,.gz,.Z}/" "n/-ffout/f:*.xvg{,.gz,.Z}/" "n/-devout/f:*.xvg{,.gz,.Z}/" "n/-runav/f:*.xvg{,.gz,.Z}/" "n/-px/f:*.xvg{,.gz,.Z}/" "n/-pf/f:*.xvg{,.gz,.Z}/" "n/-ro/f:*.xvg{,.gz,.Z}/" "n/-ra/f:*.log{,.gz,.Z}/" "n/-rs/f:*.log{,.gz,.Z}/" "n/-rt/f:*.log{,.gz,.Z}/" "n/-mtx/f:*.mtx{,.gz,.Z}/" "n/-dn/f:*.ndx{,.gz,.Z}/" "n/-bo/f:*.{trr,cpt,trj}{,.gz,.Z}/" "n/-bx/f:*.xtc{,.gz,.Z}/" "n/-bcpo/f:*.cpt{,.gz,.Z}/" "n/-bc/f:*.{gro,g96,pdb,brk,ent,esp,xyz}{,.gz,.Z}/" "n/-be/f:*.edr{,.gz,.Z}/" "n/-bg/f:*.log{,.gz,.Z}/" "n/-beo/f:*.xvg{,.gz,.Z}/" "n/-bdhdl/f:*.xvg{,.gz,.Z}/" "n/-bfield/f:*.xvg{,.gz,.Z}/" "n/-btpi/f:*.xvg{,.gz,.Z}/" "n/-btpid/f:*.xvg{,.gz,.Z}/" "n/-bjo/f:*.gct{,.gz,.Z}/" "n/-bffout/f:*.xvg{,.gz,.Z}/" "n/-bdevout/f:*.xvg{,.gz,.Z}/" "n/-brunav/f:*.xvg{,.gz,.Z}/" "n/-bpx/f:*.xvg{,.gz,.Z}/" "n/-bpf/f:*.xvg{,.gz,.Z}/" "n/-bro/f:*.xvg{,.gz,.Z}/" "n/-bra/f:*.log{,.gz,.Z}/" "n/-brs/f:*.log{,.gz,.Z}/" "n/-brt/f:*.log{,.gz,.Z}/" "n/-bmtx/f:*.mtx{,.gz,.Z}/" "n/-bdn/f:*.ndx{,.gz,.Z}/" "c/-/( p err so s o x cpi cpo c e g dhdl field table tabletf tablep tableb rerun tpi tpid ei eo j jo ffout devout runav px pf ro ra rs rt mtx dn bo bx bcpo bc be bg beo bdhdl bfield btpi btpid bjo bffout bdevout brunav bpx bpf bro bra brs brt bmtx bdn h version nice xvg np npstring ntmpi r max min npme fix rmax rmin noscalevdw ntpr steps resetstep simsteps launch nobench noappend cpnum)/"
 complete g_vanhove "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-om/f:*.xpm{,.gz,.Z}/" "n/-or/f:*.xvg{,.gz,.Z}/" "n/-ot/f:*.xvg{,.gz,.Z}/" "c/-/( f s n om or ot h version nice b e dt w xvg sqrt fm rmax rbin mmax nlevels nr fr rt ft)/"
-complete g_velacc "n/-xvg/( xmgrace xmgr none)/" "n/-P/( 0 1 2 3)/" "n/-fitfn/( none exp aexp exp_exp vac exp5 exp7 exp9)/" "n/-f/f:*.{trr,cpt,trj}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "c/-/( f s n o h version nice b e dt w xvg m mol acflen nonormalize P fitfn ncskip beginfit endfit)/"
-complete g_wham "n/-xvg/( xmgrace xmgr none)/" "n/-unit/( kJ kCal kT)/" "n/-cycl/( no yes weighted)/" "n/-ix/f:*.dat{,.gz,.Z}/" "n/-if/f:*.dat{,.gz,.Z}/" "n/-it/f:*.dat{,.gz,.Z}/" "n/-ip/f:*.dat{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-hist/f:*.xvg{,.gz,.Z}/" "n/-bsres/f:*.xvg{,.gz,.Z}/" "n/-bsprof/f:*.xvg{,.gz,.Z}/" "n/-tab/f:*.dat{,.gz,.Z}/" "n/-wcorr/f:*.xvg{,.gz,.Z}/" "c/-/( ix if it ip o hist bsres bsprof tab wcorr h version nice xvg min max noauto bins temp tol v b e dt histonly boundsonly nolog unit zprof0 cycl alpha flip hist-eq nBootstrap bs-dt bs-seed nohistbs histbs-block vbs)/"
+complete g_velacc "n/-xvg/( xmgrace xmgr none)/" "n/-P/( 0 1 2 3)/" "n/-fitfn/( none exp aexp exp_exp vac exp5 exp7 exp9 erffit)/" "n/-f/f:*.{trr,cpt,trj}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-os/f:*.xvg{,.gz,.Z}/" "c/-/( f s n o os h version nice b e dt w xvg m norecip mol acflen nonormalize P fitfn ncskip beginfit endfit)/"
+complete g_wham "n/-xvg/( xmgrace xmgr none)/" "n/-unit/( kJ kCal kT)/" "n/-bs-method/( b-hist hist traj traj-gauss)/" "n/-ix/f:*.dat{,.gz,.Z}/" "n/-if/f:*.dat{,.gz,.Z}/" "n/-it/f:*.dat{,.gz,.Z}/" "n/-ip/f:*.dat{,.gz,.Z}/" "n/-o/f:*.xvg{,.gz,.Z}/" "n/-hist/f:*.xvg{,.gz,.Z}/" "n/-oiact/f:*.xvg{,.gz,.Z}/" "n/-iiact/f:*.dat{,.gz,.Z}/" "n/-bsres/f:*.xvg{,.gz,.Z}/" "n/-bsprof/f:*.xvg{,.gz,.Z}/" "n/-tab/f:*.dat{,.gz,.Z}/" "c/-/( ix if it ip o hist oiact iiact bsres bsprof tab h version nice xvg min max noauto bins temp tol v b e dt histonly boundsonly nolog unit zprof0 cycl sym ac acsig ac-trestart nBootstrap bs-method bs-tau bs-seed histbs-block vbs)/"
 complete g_wheel "n/-f/f:*.dat{,.gz,.Z}/" "n/-o/f:*.eps{,.gz,.Z}/" "c/-/( f o h version nice r0 rot0 T nonn)/"
 complete g_x2top "n/-f/f:*.{gro,g96,pdb,brk,ent,esp,xyz,tpr,tpb,tpa}{,.gz,.Z}/" "n/-o/f:*.top{,.gz,.Z}/" "n/-r/f:*.rtp{,.gz,.Z}/" "c/-/( f o r h version nice ff v nexcl noH14 alldih remdih nopairs name nopbc pdbq noparam noround kb kt kp)/"
 complete g_xrama "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "c/-/( f s h version nice b e dt)/"
-complete genbox "n/-cp/f:*.{gro,g96,pdb,brk,ent,esp,xyz,tpr,tpb,tpa}{,.gz,.Z}/" "n/-cs/f:*.{gro,g96,pdb,brk,ent,esp,xyz,tpr,tpb,tpa}{,.gz,.Z}/" "n/-ci/f:*.{gro,g96,pdb,brk,ent,esp,xyz,tpr,tpb,tpa}{,.gz,.Z}/" "n/-o/f:*.{gro,g96,pdb,brk,ent,esp,xyz}{,.gz,.Z}/" "n/-p/f:*.top{,.gz,.Z}/" "c/-/( cp cs ci o p h version nice box nmol try seed vdwd shell maxsol vel)/"
-complete genconf "n/-f/f:*.{gro,g96,pdb,brk,ent,esp,xyz,tpr,tpb,tpa}{,.gz,.Z}/" "n/-o/f:*.{gro,g96,pdb,brk,ent,esp,xyz}{,.gz,.Z}/" "n/-trj/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "c/-/( f o trj h version nice nbox dist seed rot shuffle sort block nmolat maxrot norenumber)/"
-complete genion "n/-xvg/( xmgrace xmgr none)/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-table/f:*.xvg{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-o/f:*.{gro,g96,pdb,brk,ent,esp,xyz}{,.gz,.Z}/" "n/-g/f:*.log{,.gz,.Z}/" "n/-pot/f:*.pdb{,.gz,.Z}/" "n/-p/f:*.top{,.gz,.Z}/" "c/-/( s table n o g pot p h version nice xvg np pname pq nn nname nq rmin norandom seed scale conc neutral)/"
-complete genrestr "n/-f/f:*.{gro,g96,pdb,brk,ent,esp,xyz,tpr,tpb,tpa}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-o/f:*.itp{,.gz,.Z}/" "n/-of/f:*.ndx{,.gz,.Z}/" "c/-/( f n o of h version nice fc freeze disre disre_dist disre_frac disre_up2 cutoff constr)/"
-complete gmxcheck "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-f2/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s1/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-s2/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-c/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-e/f:*.edr{,.gz,.Z}/" "n/-e2/f:*.edr{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-m/f:*.tex{,.gz,.Z}/" "c/-/( f f2 s1 s2 c e e2 n m h version nice vdwfac bonlo bonhi rmsd tol abstol ab lastener)/"
-complete gmxdump "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-e/f:*.edr{,.gz,.Z}/" "n/-cp/f:*.cpt{,.gz,.Z}/" "n/-p/f:*.top{,.gz,.Z}/" "n/-mtx/f:*.mtx{,.gz,.Z}/" "n/-om/f:*.mdp{,.gz,.Z}/" "c/-/( s f e cp p mtx om h version nice nonr sys)/"
-complete grompp "n/-f/f:*.mdp{,.gz,.Z}/" "n/-po/f:*.mdp{,.gz,.Z}/" "n/-c/f:*.{gro,g96,pdb,brk,ent,esp,xyz,tpr,tpb,tpa}{,.gz,.Z}/" "n/-r/f:*.{gro,g96,pdb,brk,ent,esp,xyz,tpr,tpb,tpa}{,.gz,.Z}/" "n/-rb/f:*.{gro,g96,pdb,brk,ent,esp,xyz,tpr,tpb,tpa}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-p/f:*.top{,.gz,.Z}/" "n/-pp/f:*.top{,.gz,.Z}/" "n/-o/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-t/f:*.{trr,cpt,trj}{,.gz,.Z}/" "n/-e/f:*.edr{,.gz,.Z}/" "c/-/( f po c r rb n p pp o t e h version nice v time normvsbds maxwarn zero norenum)/"
-complete make_edi "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.{trr,cpt,trj}{,.gz,.Z}/" "n/-eig/f:*.xvg{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-tar/f:*.{gro,g96,pdb,brk,ent,esp,xyz,tpr,tpb,tpa}{,.gz,.Z}/" "n/-ori/f:*.{gro,g96,pdb,brk,ent,esp,xyz,tpr,tpb,tpa}{,.gz,.Z}/" "n/-o/f:*.edi{,.gz,.Z}/" "c/-/( f eig s n tar ori o h version nice xvg mon linfix linacc flood radfix radacc radcon outfrq slope maxedsteps deltaF0 deltaF tau eqsteps Eflnull T alpha linstep accdir radstep restrain hessian harmonic)/"
+complete make_edi "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.{trr,cpt,trj}{,.gz,.Z}/" "n/-eig/f:*.xvg{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-tar/f:*.{gro,g96,pdb,brk,ent,esp,xyz,tpr,tpb,tpa}{,.gz,.Z}/" "n/-ori/f:*.{gro,g96,pdb,brk,ent,esp,xyz,tpr,tpb,tpa}{,.gz,.Z}/" "n/-o/f:*.edi{,.gz,.Z}/" "c/-/( f eig s n tar ori o h version nice xvg mon linfix linacc radfix radacc radcon flood outfrq slope linstep accdir radstep maxedsteps eqsteps deltaF0 deltaF tau Eflnull T alpha restrain hessian harmonic constF)/"
 complete make_ndx "n/-f/f:*.{gro,g96,pdb,brk,ent,esp,xyz,tpr,tpb,tpa}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-o/f:*.ndx{,.gz,.Z}/" "c/-/( f n o h version nice natoms)/"
-complete mdrun "n/-xvg/( xmgrace xmgr none)/" "n/-ddorder/( interleave pp_pme cartesian)/" "n/-dlb/( auto no yes)/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-o/f:*.{trr,cpt,trj}{,.gz,.Z}/" "n/-x/f:*.xtc{,.gz,.Z}/" "n/-cpi/f:*.cpt{,.gz,.Z}/" "n/-cpo/f:*.cpt{,.gz,.Z}/" "n/-c/f:*.{gro,g96,pdb,brk,ent,esp,xyz}{,.gz,.Z}/" "n/-e/f:*.edr{,.gz,.Z}/" "n/-g/f:*.log{,.gz,.Z}/" "n/-dhdl/f:*.xvg{,.gz,.Z}/" "n/-field/f:*.xvg{,.gz,.Z}/" "n/-table/f:*.xvg{,.gz,.Z}/" "n/-tablep/f:*.xvg{,.gz,.Z}/" "n/-tableb/f:*.xvg{,.gz,.Z}/" "n/-rerun/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-tpi/f:*.xvg{,.gz,.Z}/" "n/-tpid/f:*.xvg{,.gz,.Z}/" "n/-ei/f:*.edi{,.gz,.Z}/" "n/-eo/f:*.edo{,.gz,.Z}/" "n/-j/f:*.gct{,.gz,.Z}/" "n/-jo/f:*.gct{,.gz,.Z}/" "n/-ffout/f:*.xvg{,.gz,.Z}/" "n/-devout/f:*.xvg{,.gz,.Z}/" "n/-runav/f:*.xvg{,.gz,.Z}/" "n/-px/f:*.xvg{,.gz,.Z}/" "n/-pf/f:*.xvg{,.gz,.Z}/" "n/-mtx/f:*.mtx{,.gz,.Z}/" "n/-dn/f:*.ndx{,.gz,.Z}/" "c/-/( s o x cpi cpo c e g dhdl field table tablep tableb rerun tpi tpid ei eo j jo ffout devout runav px pf mtx dn h version nice deffnm xvg pd dd nt npme ddorder noddcheck rdd rcon dlb dds gcom v nocompact seppot pforce reprod cpt cpnum noappend maxh multi replex reseed ionize)/"
+complete mdrun "n/-xvg/( xmgrace xmgr none)/" "n/-ddorder/( interleave pp_pme cartesian)/" "n/-dlb/( auto no yes)/" "n/-nb/( auto cpu gpu gpu_cpu)/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-o/f:*.{trr,cpt,trj}{,.gz,.Z}/" "n/-x/f:*.xtc{,.gz,.Z}/" "n/-cpi/f:*.cpt{,.gz,.Z}/" "n/-cpo/f:*.cpt{,.gz,.Z}/" "n/-c/f:*.{gro,g96,pdb,brk,ent,esp,xyz}{,.gz,.Z}/" "n/-e/f:*.edr{,.gz,.Z}/" "n/-g/f:*.log{,.gz,.Z}/" "n/-dhdl/f:*.xvg{,.gz,.Z}/" "n/-field/f:*.xvg{,.gz,.Z}/" "n/-table/f:*.xvg{,.gz,.Z}/" "n/-tabletf/f:*.xvg{,.gz,.Z}/" "n/-tablep/f:*.xvg{,.gz,.Z}/" "n/-tableb/f:*.xvg{,.gz,.Z}/" "n/-rerun/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-tpi/f:*.xvg{,.gz,.Z}/" "n/-tpid/f:*.xvg{,.gz,.Z}/" "n/-ei/f:*.edi{,.gz,.Z}/" "n/-eo/f:*.xvg{,.gz,.Z}/" "n/-j/f:*.gct{,.gz,.Z}/" "n/-jo/f:*.gct{,.gz,.Z}/" "n/-ffout/f:*.xvg{,.gz,.Z}/" "n/-devout/f:*.xvg{,.gz,.Z}/" "n/-runav/f:*.xvg{,.gz,.Z}/" "n/-px/f:*.xvg{,.gz,.Z}/" "n/-pf/f:*.xvg{,.gz,.Z}/" "n/-ro/f:*.xvg{,.gz,.Z}/" "n/-ra/f:*.log{,.gz,.Z}/" "n/-rs/f:*.log{,.gz,.Z}/" "n/-rt/f:*.log{,.gz,.Z}/" "n/-mtx/f:*.mtx{,.gz,.Z}/" "n/-dn/f:*.ndx{,.gz,.Z}/" "n/-multidir/f:*.rundir{,.gz,.Z}/" "n/-membed/f:*.dat{,.gz,.Z}/" "n/-mp/f:*.top{,.gz,.Z}/" "n/-mn/f:*.ndx{,.gz,.Z}/" "c/-/( s o x cpi cpo c e g dhdl field table tabletf tablep tableb rerun tpi tpid ei eo j jo ffout devout runav px pf ro ra rs rt mtx dn multidir membed mp mn h version nice deffnm xvg pd dd ddorder npme nt ntmpi ntomp ntomp_pme nopin pinht pinoffset gpu_id noddcheck rdd rcon dlb dds gcom nb notunepme testverlet v nocompact seppot pforce reprod cpt cpnum noappend nsteps maxh multi replex nex reseed ionize)/"
+complete mdrun_mpi "n/-xvg/( xmgrace xmgr none)/" "n/-ddorder/( interleave pp_pme cartesian)/" "n/-dlb/( auto no yes)/" "n/-nb/( auto cpu gpu gpu_cpu)/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-o/f:*.{trr,cpt,trj}{,.gz,.Z}/" "n/-x/f:*.xtc{,.gz,.Z}/" "n/-cpi/f:*.cpt{,.gz,.Z}/" "n/-cpo/f:*.cpt{,.gz,.Z}/" "n/-c/f:*.{gro,g96,pdb,brk,ent,esp,xyz}{,.gz,.Z}/" "n/-e/f:*.edr{,.gz,.Z}/" "n/-g/f:*.log{,.gz,.Z}/" "n/-dhdl/f:*.xvg{,.gz,.Z}/" "n/-field/f:*.xvg{,.gz,.Z}/" "n/-table/f:*.xvg{,.gz,.Z}/" "n/-tabletf/f:*.xvg{,.gz,.Z}/" "n/-tablep/f:*.xvg{,.gz,.Z}/" "n/-tableb/f:*.xvg{,.gz,.Z}/" "n/-rerun/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-tpi/f:*.xvg{,.gz,.Z}/" "n/-tpid/f:*.xvg{,.gz,.Z}/" "n/-ei/f:*.edi{,.gz,.Z}/" "n/-eo/f:*.edo{,.gz,.Z}/" "n/-j/f:*.gct{,.gz,.Z}/" "n/-jo/f:*.gct{,.gz,.Z}/" "n/-ffout/f:*.xvg{,.gz,.Z}/" "n/-devout/f:*.xvg{,.gz,.Z}/" "n/-runav/f:*.xvg{,.gz,.Z}/" "n/-px/f:*.xvg{,.gz,.Z}/" "n/-pf/f:*.xvg{,.gz,.Z}/" "n/-ro/f:*.xvg{,.gz,.Z}/" "n/-ra/f:*.log{,.gz,.Z}/" "n/-rs/f:*.log{,.gz,.Z}/" "n/-rt/f:*.log{,.gz,.Z}/" "n/-mtx/f:*.mtx{,.gz,.Z}/" "n/-dn/f:*.ndx{,.gz,.Z}/" "n/-multidir/f:*.rundir{,.gz,.Z}/" "n/-membed/f:*.dat{,.gz,.Z}/" "n/-mp/f:*.top{,.gz,.Z}/" "n/-mn/f:*.ndx{,.gz,.Z}/" "c/-/( s o x cpi cpo c e g dhdl field table tabletf tablep tableb rerun tpi tpid ei eo j jo ffout devout runav px pf ro ra rs rt mtx dn multidir membed mp mn h version nice deffnm xvg pd dd ddorder npme nt ntmpi ntomp ntomp_pme nopin pinht pinoffset gpu_id noddcheck rdd rcon dlb dds gcom nb notunepme testverlet v nocompact seppot pforce reprod cpt cpnum noappend nsteps maxh multi replex nex reseed ionize)/"
 complete mk_angndx "n/-type/( angle dihedral improper ryckaert-bellemans)/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "c/-/( s n h version nice type nohyd hq)/"
 complete ngmx "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "c/-/( f s n h version nice b e dt)/"
-complete pdb2gmx "n/-chainsep/( id_or_ter id_and_ter ter id interactive)/" "n/-water/( select none spc spce tip3p tip4p tip5p)/" "n/-vsite/( none hydrogens aromatics)/" "n/-f/f:*.{gro,g96,pdb,brk,ent,esp,xyz,tpr,tpb,tpa}{,.gz,.Z}/" "n/-o/f:*.{gro,g96,pdb,brk,ent,esp,xyz}{,.gz,.Z}/" "n/-p/f:*.top{,.gz,.Z}/" "n/-i/f:*.itp{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-q/f:*.{gro,g96,pdb,brk,ent,esp,xyz}{,.gz,.Z}/" "c/-/( f o p i n q h version nice chainsep ff water inter ss ter lys arg asp glu gln his angle dist una ignh missing v posrefc vsite heavyh deuterate nochargegrp nocmap renum rtpres)/"
-complete tpbconv "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-f/f:*.{trr,cpt,trj}{,.gz,.Z}/" "n/-e/f:*.edr{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-o/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "c/-/( s f e n o h version nice extend until nsteps time zeroq novel nocont)/"
+complete pdb2gmx "n/-chainsep/( id_or_ter id_and_ter ter id interactive)/" "n/-merge/( no all interactive)/" "n/-water/( select none spc spce tip3p tip4p tip5p)/" "n/-vsite/( none hydrogens aromatics)/" "n/-f/f:*.{gro,g96,pdb,brk,ent,esp,xyz,tpr,tpb,tpa}{,.gz,.Z}/" "n/-o/f:*.{gro,g96,pdb,brk,ent,esp,xyz}{,.gz,.Z}/" "n/-p/f:*.top{,.gz,.Z}/" "n/-i/f:*.itp{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-q/f:*.{gro,g96,pdb,brk,ent,esp,xyz}{,.gz,.Z}/" "c/-/( f o p i n q h version nice chainsep merge ff water inter ss ter lys arg asp glu gln his angle dist una ignh missing v posrefc vsite heavyh deuterate nochargegrp nocmap renum rtpres)/"
+complete tpbconv "n/-s/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "n/-f/f:*.{trr,cpt,trj}{,.gz,.Z}/" "n/-e/f:*.edr{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-o/f:*.{tpr,tpb,tpa}{,.gz,.Z}/" "c/-/( s f e n o h version nice extend until nsteps time zeroq novel nocont init_fep_state)/"
 complete trjcat "n/-tu/( fs ps ns us ms s)/" "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-o/f:*.{xtc,trr,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-demux/f:*.xvg{,.gz,.Z}/" "c/-/( f o n demux h version nice tu xvg b e dt prec novel settime nosort keeplast overwrite cat)/"
-complete trjconv "n/-tu/( fs ps ns us ms s)/" "n/-xvg/( xmgrace xmgr none)/" "n/-pbc/( none mol res atom nojump cluster whole)/" "n/-ur/( rect tric compact)/" "n/-boxcenter/( tric rect zero)/" "n/-fit/( none rot+trans rotxy+transxy translation transxy progressive)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-o/f:*.{xtc,trr,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-fr/f:*.ndx{,.gz,.Z}/" "n/-sub/f:*.ndx{,.gz,.Z}/" "n/-drop/f:*.xvg{,.gz,.Z}/" "c/-/( f o s n fr sub drop h version nice b e tu w xvg skip dt round dump t0 timestep pbc ur center boxcenter box trans shift fit ndec novel force trunc exec app split sep nzero dropunder dropover conect)/"
+complete trjconv "n/-tu/( fs ps ns us ms s)/" "n/-xvg/( xmgrace xmgr none)/" "n/-pbc/( none mol res atom nojump cluster whole)/" "n/-ur/( rect tric compact)/" "n/-boxcenter/( tric rect zero)/" "n/-fit/( none rot+trans rotxy+transxy translation transxy progressive)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-o/f:*.{xtc,trr,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-fr/f:*.ndx{,.gz,.Z}/" "n/-sub/f:*.ndx{,.gz,.Z}/" "n/-drop/f:*.xvg{,.gz,.Z}/" "c/-/( f o s n fr sub drop h version nice b e tu w xvg skip dt round dump t0 timestep pbc ur center boxcenter box clustercenter trans shift fit ndec novel force trunc exec app split sep nzero dropunder dropover conect)/"
 complete trjorder "n/-xvg/( xmgrace xmgr none)/" "n/-f/f:*.{xtc,trr,cpt,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-s/f:*.{tpr,tpb,tpa,gro,g96,pdb,brk,ent}{,.gz,.Z}/" "n/-n/f:*.ndx{,.gz,.Z}/" "n/-o/f:*.{xtc,trr,trj,gro,g96,pdb,g87}{,.gz,.Z}/" "n/-nshell/f:*.xvg{,.gz,.Z}/" "c/-/( f s n o nshell h version nice b e dt xvg na da com r z)/"
 complete xpm2ps "n/-title/( top once ylabel none)/" "n/-legend/( both first second none)/" "n/-diag/( first second none)/" "n/-rainbow/( no blue red)/" "n/-combine/( halves add sub mult div)/" "n/-f/f:*.xpm{,.gz,.Z}/" "n/-f2/f:*.xpm{,.gz,.Z}/" "n/-di/f:*.m2p{,.gz,.Z}/" "n/-do/f:*.m2p{,.gz,.Z}/" "n/-o/f:*.eps{,.gz,.Z}/" "n/-xpm/f:*.xpm{,.gz,.Z}/" "c/-/( f f2 di do o xpm h version nice w noframe title yonce legend diag size bx by rainbow gradient skip zeroline legoffset combine cmin cmax)/"
index ae0d742efee406bd9d93f566ed95af1dfb2e4815..0f876f05ae0128b675dad300a43b0646fadfb072 100644 (file)
@@ -1,45 +1,57 @@
-compctl  -x 's[-]' -s " f s n ssdump map o sc a ta aa h version nice b e dt tu w xvg sss" - 'c[-1,-tu]' -s " fs ps ns us ms s" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-ssdump]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-map]' -g '*.map(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-sc]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-a]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-ta]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-aa]' -g '*.xvg(|.gz|.Z) *(/)' -- do_dssp
-compctl  -x 's[-]' -s " f n o mead bf h version nice w ndef bt box angles d c center aligncenter align translate rotate princ scale density pbc grasp rvdw sig56 vdwread atom legend label conect" - 'c[-1,-bt]' -s " triclinic cubic dodecahedron octahedron" - 'c[-1,-f]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz)(|.gz|.Z) *(/)' - 'c[-1,-mead]' -g '*.pqr(|.gz|.Z) *(/)' - 'c[-1,-bf]' -g '*.dat(|.gz|.Z) *(/)' -- editconf
-compctl  -x 's[-]' -s " f o h version nice b e dt offset settime nosort scalefac noerror" - 'c[-1,-f]' -g '*.edr(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.edr(|.gz|.Z) *(/)' -- eneconv
+compctl  -x 's[-]' -s " f s n ssdump map o sc a ta aa h version nice b e dt tu w xvg sss ver" - 'c[-1,-tu]' -s " fs ps ns us ms s" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-ssdump]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-map]' -g '*.map(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-sc]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-a]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-ta]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-aa]' -g '*.xvg(|.gz|.Z) *(/)' -- do_dssp
+compctl  -x 's[-]' -s " f n o mead bf h version nice w ndef bt box angles d c center aligncenter align translate rotate princ scale density pbc resnr grasp rvdw sig56 vdwread atom legend label conect" - 'c[-1,-bt]' -s " triclinic cubic dodecahedron octahedron" - 'c[-1,-f]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz)(|.gz|.Z) *(/)' - 'c[-1,-mead]' -g '*.pqr(|.gz|.Z) *(/)' - 'c[-1,-bf]' -g '*.dat(|.gz|.Z) *(/)' -- editconf
+compctl  -x 's[-]' -s " f o h version nice b e dt offset settime nosort rmdh scalefac noerror" - 'c[-1,-f]' -g '*.edr(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.edr(|.gz|.Z) *(/)' -- eneconv
 compctl  -x 's[-]' -s " f ox od of g h version nice xvg free norms cutoff" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.pdb(|.gz|.Z) *(/)' - 'c[-1,-ox]' -g '*.pdb(|.gz|.Z) *(/)' - 'c[-1,-od]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-of]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-g]' -g '*.log(|.gz|.Z) *(/)' -- g_anadock
 compctl  -x 's[-]' -s " v v2 f s n eig eig2 comp rmsf proj 2d 3d filt extr over inpr h version nice b e dt tu w xvg first last skip max nframes split entropy temp nevskip" - 'c[-1,-tu]' -s " fs ps ns us ms s" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-v]' -g '*.(trr|cpt|trj)(|.gz|.Z) *(/)' - 'c[-1,-v2]' -g '*.(trr|cpt|trj)(|.gz|.Z) *(/)' - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-eig]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-eig2]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-comp]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-rmsf]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-proj]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-2d]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-3d]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz)(|.gz|.Z) *(/)' - 'c[-1,-filt]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-extr]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-over]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-inpr]' -g '*.xpm(|.gz|.Z) *(/)' -- g_anaeig
-compctl  -x 's[-]' -s " f ac msd cc dist av ee bal g h version nice w xvg notime b e n d bw errbar integrate aver_start xydy regression luzar temp fitstart fitend smooth filter power nosubav oneacf acflen nonormalize P fitfn ncskip beginfit endfit" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-errbar]' -s " none stddev error 90" - 'c[-1,-P]' -s " 0 1 2 3" - 'c[-1,-fitfn]' -s " none exp aexp exp_exp vac exp5 exp7 exp9" - 'c[-1,-f]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ac]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-msd]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-cc]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-dist]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-av]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ee]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-bal]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-g]' -g '*.log(|.gz|.Z) *(/)' -- g_analyze
-compctl  -x 's[-]' -s " f n od ov of ot oh oc or h version nice b e dt w xvg type all binwidth noperiodic chandler avercorr acflen nonormalize P fitfn ncskip beginfit endfit" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-type]' -s " angle dihedral improper ryckaert-bellemans" - 'c[-1,-P]' -s " 0 1 2 3" - 'c[-1,-fitfn]' -s " none exp aexp exp_exp vac exp5 exp7 exp9" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-od]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ov]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-of]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ot]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-oh]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-oc]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-or]' -g '*.trr(|.gz|.Z) *(/)' -- g_angle
-compctl  -x 's[-]' -s " f o oi oh g h version nice w xvg b e temp prec nbmin nbmax nbin" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-oi]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-oh]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-g]' -g '*.edr(|.gz|.Z) *(/)' -- g_bar
+compctl  -x 's[-]' -s " f ac msd cc dist av ee bal g h version nice w xvg notime b e n d bw errbar integrate aver_start xydy regression luzar temp fitstart fitend smooth filter power nosubav oneacf acflen nonormalize P fitfn ncskip beginfit endfit" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-errbar]' -s " none stddev error 90" - 'c[-1,-P]' -s " 0 1 2 3" - 'c[-1,-fitfn]' -s " none exp aexp exp_exp vac exp5 exp7 exp9 erffit" - 'c[-1,-f]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ac]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-msd]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-cc]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-dist]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-av]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ee]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-bal]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-g]' -g '*.log(|.gz|.Z) *(/)' -- g_analyze
+compctl  -x 's[-]' -s " f n od ov of ot oh oc or h version nice b e dt w xvg type all binwidth noperiodic chandler avercorr acflen nonormalize P fitfn ncskip beginfit endfit" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-type]' -s " angle dihedral improper ryckaert-bellemans" - 'c[-1,-P]' -s " 0 1 2 3" - 'c[-1,-fitfn]' -s " none exp aexp exp_exp vac exp5 exp7 exp9 erffit" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-od]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ov]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-of]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ot]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-oh]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-oc]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-or]' -g '*.trr(|.gz|.Z) *(/)' -- g_angle
+compctl  -x 's[-]' -s " f g o oi oh h version nice w xvg b e temp prec nbmin nbmax nbin extp" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-g]' -g '*.edr(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-oi]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-oh]' -g '*.xvg(|.gz|.Z) *(/)' -- g_bar
 compctl  -x 's[-]' -s " f n s o l d h version nice b e dt w xvg blen tol noaver noaverdist" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-l]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-d]' -g '*.xvg(|.gz|.Z) *(/)' -- g_bond
 compctl  -x 's[-]' -s " f s n ol od oz ot otr otl ok okr okl oa h version nice b e dt tu xvg na z" - 'c[-1,-tu]' -s " fs ps ns us ms s" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-ol]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-od]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-oz]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ot]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-otr]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-otl]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ok]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-okr]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-okl]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-oa]' -g '*.pdb(|.gz|.Z) *(/)' -- g_bundle
-compctl  -x 's[-]' -s " s f o p ss jc corr g ot oh rt cp h version nice b e dt w xvg r0 phi psi omega rama viol noperiodic all rad shift binwidth core_rotamer maxchi nonormhisto ramomega bfact chi_prod HChi bmax acflen nonormalize P fitfn ncskip beginfit endfit" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-maxchi]' -s " 0 1 2 3 4 5 6" - 'c[-1,-P]' -s " 0 1 2 3" - 'c[-1,-fitfn]' -s " none exp aexp exp_exp vac exp5 exp7 exp9" - 'c[-1,-s]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-p]' -g '*.pdb(|.gz|.Z) *(/)' - 'c[-1,-ss]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-jc]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-corr]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-g]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-ot]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-oh]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-rt]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-cp]' -g '*.xvg(|.gz|.Z) *(/)' -- g_chi
-compctl  -x 's[-]' -s " f s n dm o g dist ev sz tr ntr clid cl h version nice b e dt tu w xvg dista nlevels cutoff nofit max skip av wcl nst rmsmin method minstruct binary M P seed niter kT" - 'c[-1,-tu]' -s " fs ps ns us ms s" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-method]' -s " linkage jarvis-patrick monte-carlo diagonalization gromos" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-dm]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-g]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-dist]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ev]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-sz]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-tr]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-ntr]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-clid]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-cl]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' -- g_cluster
+compctl  -x 's[-]' -s " s f o p ss jc corr g ot oh rt cp h version nice b e dt w xvg r0 phi psi omega rama viol noperiodic all rad shift binwidth core_rotamer maxchi nonormhisto ramomega bfact chi_prod HChi bmax acflen nonormalize P fitfn ncskip beginfit endfit" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-maxchi]' -s " 0 1 2 3 4 5 6" - 'c[-1,-P]' -s " 0 1 2 3" - 'c[-1,-fitfn]' -s " none exp aexp exp_exp vac exp5 exp7 exp9 erffit" - 'c[-1,-s]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-p]' -g '*.pdb(|.gz|.Z) *(/)' - 'c[-1,-ss]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-jc]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-corr]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-g]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-ot]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-oh]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-rt]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-cp]' -g '*.xvg(|.gz|.Z) *(/)' -- g_chi
+compctl  -x 's[-]' -s " f s n dm o g dist ev sz tr ntr clid cl h version nice b e dt tu w xvg dista nlevels cutoff nofit max skip av wcl nst rmsmin method minstruct binary M P seed niter kT nopbc" - 'c[-1,-tu]' -s " fs ps ns us ms s" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-method]' -s " linkage jarvis-patrick monte-carlo diagonalization gromos" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-dm]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-g]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-dist]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ev]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-sz]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-tr]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-ntr]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-clid]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-cl]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' -- g_cluster
 compctl  -x 's[-]' -s " f s n o ow nc mc ac hc temp mcn h version nice b e dt tu w xvg cut mol nopbc nskip nlevels ndf rgblo rgbhi" - 'c[-1,-tu]' -s " fs ps ns us ms s" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.tpr(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-ow]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-nc]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-mc]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ac]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-hc]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-temp]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-mcn]' -g '*.ndx(|.gz|.Z) *(/)' -- g_clustsize
 compctl  -x 's[-]' -s " f1 f2 o n1 n2 no h version nice w one nomw pbc nofit name label bfac" - 'c[-1,-f1]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-f2]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz)(|.gz|.Z) *(/)' - 'c[-1,-n1]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-n2]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-no]' -g '*.ndx(|.gz|.Z) *(/)' -- g_confrms
 compctl  -x 's[-]' -s " f s n o v av l ascii xpm xpma h version nice b e dt tu xvg nofit ref mwa last nopbc" - 'c[-1,-tu]' -s " fs ps ns us ms s" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-v]' -g '*.(trr|cpt|trj)(|.gz|.Z) *(/)' - 'c[-1,-av]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz)(|.gz|.Z) *(/)' - 'c[-1,-l]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-ascii]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-xpm]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-xpma]' -g '*.xpm(|.gz|.Z) *(/)' -- g_covar
 compctl  -x 's[-]' -s " s n f o caf dsp md mj mc h version nice b e dt w xvg sh nonojump eps bfit efit bvit evit tr temp" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-caf]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-dsp]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-md]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-mj]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-mc]' -g '*.xvg(|.gz|.Z) *(/)' -- g_current
 compctl  -x 's[-]' -s " f n s ei o h version nice b e dt w xvg d sl dens ng symm center" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-dens]' -s " mass number charge electron" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-ei]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' -- g_density
 compctl  -x 's[-]' -s " f s n od o h version nice b e dt w bin aver xmin xmax n1 n2 amax rmax mirror sums unit dmin dmax" - 'c[-1,-aver]' -s " z y x" - 'c[-1,-unit]' -s " nm-3 nm-2 count" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-od]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xpm(|.gz|.Z) *(/)' -- g_densmap
-compctl  -x 's[-]' -s " f d o c h version nice b e dt w xvg fft nox1 eint bfit efit tail A tau1 tau2 eps0 epsRF fix ffn nsmooth" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-ffn]' -s " none exp aexp exp_exp vac exp5 exp7 exp9" - 'c[-1,-f]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-d]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-c]' -g '*.xvg(|.gz|.Z) *(/)' -- g_dielectric
-compctl  -x 's[-]' -s " f s o h version nice b e dt w sa mult" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.out(|.gz|.Z) *(/)' -- g_dih
-compctl  -x 's[-]' -s " en f s n o eps a d c g adip dip3d cos cmap q slab h version nice b e dt w xvg mu mumax epsilonRF skip temp corr nopairs ncos axis sl gkratom gkratom2 rcmax phi nlevels ndegrees acflen nonormalize P fitfn ncskip beginfit endfit" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-corr]' -s " none mol molsep total" - 'c[-1,-P]' -s " 0 1 2 3" - 'c[-1,-fitfn]' -s " none exp aexp exp_exp vac exp5 exp7 exp9" - 'c[-1,-en]' -g '*.edr(|.gz|.Z) *(/)' - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-eps]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-a]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-d]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-c]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-g]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-adip]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-dip3d]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-cos]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-cmap]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-q]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-slab]' -g '*.xvg(|.gz|.Z) *(/)' -- g_dipoles
+compctl  -x 's[-]' -s " s f n o or og Spect h version nice b e dt w 1d bw bwn order axis method d1 d2 tblock nlevel" - 'c[-1,-method]' -s " bisect functional" - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-or]' -g '*.out(|.gz|.Z) *(/)' - 'c[-1,-og]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-Spect]' -g '*.out(|.gz|.Z) *(/)' -- g_densorder
+compctl  -x 's[-]' -s " f d o c h version nice b e dt w xvg fft nox1 eint bfit efit tail A tau1 tau2 eps0 epsRF fix ffn nsmooth" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-ffn]' -s " none exp aexp exp_exp vac exp5 exp7 exp9 erffit" - 'c[-1,-f]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-d]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-c]' -g '*.xvg(|.gz|.Z) *(/)' -- g_dielectric
+compctl  -x 's[-]' -s " en f s n o eps a d c g adip dip3d cos cmap q slab h version nice b e dt w xvg mu mumax epsilonRF skip temp corr nopairs ncos axis sl gkratom gkratom2 rcmax phi nlevels ndegrees acflen nonormalize P fitfn ncskip beginfit endfit" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-corr]' -s " none mol molsep total" - 'c[-1,-P]' -s " 0 1 2 3" - 'c[-1,-fitfn]' -s " none exp aexp exp_exp vac exp5 exp7 exp9 erffit" - 'c[-1,-en]' -g '*.edr(|.gz|.Z) *(/)' - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-eps]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-a]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-d]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-c]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-g]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-adip]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-dip3d]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-cos]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-cmap]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-q]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-slab]' -g '*.xvg(|.gz|.Z) *(/)' -- g_dipoles
 compctl  -x 's[-]' -s " s f ds da dn dm dr l n q c x h version nice b e dt w xvg ntop maxdr nlevels nothird" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-ds]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-da]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-dn]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-dm]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-dr]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-l]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-q]' -g '*.pdb(|.gz|.Z) *(/)' - 'c[-1,-c]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-x]' -g '*.xpm(|.gz|.Z) *(/)' -- g_disre
-compctl  -x 's[-]' -s " f s n o lt h version nice b e dt xvg dist" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-lt]' -g '*.xvg(|.gz|.Z) *(/)' -- g_dist
+compctl  -x 's[-]' -s " f s n o lt h version nice b e dt xvg intra dist" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-lt]' -g '*.xvg(|.gz|.Z) *(/)' -- g_dist
+compctl  -x 's[-]' -s " f s n vacf mvacf dos g h version nice b e dt w xvg nov recip abs normdos T acflen nonormalize P fitfn ncskip beginfit endfit" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-P]' -s " 0 1 2 3" - 'c[-1,-fitfn]' -s " none exp aexp exp_exp vac exp5 exp7 exp9 erffit" - 'c[-1,-f]' -g '*.(trr|cpt|trj)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-vacf]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-mvacf]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-dos]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-g]' -g '*.log(|.gz|.Z) *(/)' -- g_dos
+compctl  -x 's[-]' -s " f n ot oe o rhist khist h version nice b e tu w xvg pbcdist norm bins R0" - 'c[-1,-tu]' -s " fs ps ns us ms s" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-ot]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-oe]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-rhist]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-khist]' -g '*.xvg(|.gz|.Z) *(/)' -- g_dyecoupl
 compctl  -x 's[-]' -s " f o n h version nice firstangle lastangle nframe maxangle trans head tail" - 'c[-1,-f]' -g '*.pdb(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.(xtc|trr|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' -- g_dyndom
-compctl  -x 's[-]' -s " f groups eref emat etot h version nice b e dt w xvg sum skip nomean nlevels max min nocoul coulr coul14 nolj lj lj14 bhamsr bhamlr nofree temp" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.edr(|.gz|.Z) *(/)' - 'c[-1,-groups]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-eref]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-emat]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-etot]' -g '*.xvg(|.gz|.Z) *(/)' -- g_enemat
-compctl  -x 's[-]' -s " f f2 s o viol pairs ora ort oda odr odt oten corr vis ravg h version nice b e w xvg fee fetemp zero sum dp nbmin nbmax mutot skip aver nmol nconstr fluc orinst ovec acflen nonormalize P fitfn ncskip beginfit endfit" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-P]' -s " 0 1 2 3" - 'c[-1,-fitfn]' -s " none exp aexp exp_exp vac exp5 exp7 exp9" - 'c[-1,-f]' -g '*.edr(|.gz|.Z) *(/)' - 'c[-1,-f2]' -g '*.edr(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-viol]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-pairs]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ora]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ort]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-oda]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-odr]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-odt]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-oten]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-corr]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-vis]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ravg]' -g '*.xvg(|.gz|.Z) *(/)' -- g_energy
+compctl  -x 's[-]' -s " cp cs ci o p h version nice box nmol try seed vdwd shell maxsol vel" - 'c[-1,-cp]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-cs]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-ci]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz)(|.gz|.Z) *(/)' - 'c[-1,-p]' -g '*.top(|.gz|.Z) *(/)' -- genbox
+compctl  -x 's[-]' -s " f o trj h version nice nbox dist seed rot shuffle sort block nmolat maxrot norenumber" - 'c[-1,-f]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz)(|.gz|.Z) *(/)' - 'c[-1,-trj]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' -- genconf
+compctl  -x 's[-]' -s " f groups eref emat etot h version nice b e dt w xvg sum skip nomean nlevels max min nocoulsr coullr coul14 noljsr ljlr lj14 bhamsr bhamlr nofree temp" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.edr(|.gz|.Z) *(/)' - 'c[-1,-groups]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-eref]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-emat]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-etot]' -g '*.xvg(|.gz|.Z) *(/)' -- g_enemat
+compctl  -x 's[-]' -s " f f2 s o viol pairs ora ort oda odr odt oten corr vis ravg odh h version nice b e w xvg fee fetemp zero sum dp nbmin nbmax mutot skip aver nmol fluct_props driftcorr fluc orinst ovec acflen nonormalize P fitfn ncskip beginfit endfit" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-P]' -s " 0 1 2 3" - 'c[-1,-fitfn]' -s " none exp aexp exp_exp vac exp5 exp7 exp9 erffit" - 'c[-1,-f]' -g '*.edr(|.gz|.Z) *(/)' - 'c[-1,-f2]' -g '*.edr(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-viol]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-pairs]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ora]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ort]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-oda]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-odr]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-odt]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-oten]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-corr]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-vis]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ravg]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-odh]' -g '*.xvg(|.gz|.Z) *(/)' -- g_energy
+compctl  -x 's[-]' -s " s table n o g pot p h version nice xvg np pname pq nn nname nq rmin norandom seed scale conc neutral" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-table]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz)(|.gz|.Z) *(/)' - 'c[-1,-g]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-pot]' -g '*.pdb(|.gz|.Z) *(/)' - 'c[-1,-p]' -g '*.top(|.gz|.Z) *(/)' -- genion
+compctl  -x 's[-]' -s " f n o of h version nice fc freeze disre disre_dist disre_frac disre_up2 cutoff constr" - 'c[-1,-f]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.itp(|.gz|.Z) *(/)' - 'c[-1,-of]' -g '*.ndx(|.gz|.Z) *(/)' -- genrestr
 compctl  -x 's[-]' -s " f s n ol oh h version nice b e dt w nf all nonojump fit" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-ol]' -g '*.(xtc|trr|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-oh]' -g '*.(xtc|trr|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' -- g_filter
-compctl  -x 's[-]' -s " f s n o acf h version nice b e dt w xvg nmol q p moi nz acflen nonormalize P fitfn ncskip beginfit endfit" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-P]' -s " 0 1 2 3" - 'c[-1,-fitfn]' -s " none exp aexp exp_exp vac exp5 exp7 exp9" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-acf]' -g '*.xvg(|.gz|.Z) *(/)' -- g_gyrate
+compctl  -x 's[-]' -s " f s n o acf h version nice b e dt w xvg nmol q p moi nz acflen nonormalize P fitfn ncskip beginfit endfit" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-P]' -s " 0 1 2 3" - 'c[-1,-fitfn]' -s " none exp aexp exp_exp vac exp5 exp7 exp9 erffit" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-acf]' -g '*.xvg(|.gz|.Z) *(/)' -- g_gyrate
 compctl  -x 's[-]' -s " f n nm s o h version nice b e dt w xvg d sl" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-nm]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' -- g_h2order
-compctl  -x 's[-]' -s " f s n num g ac dist ang hx hbn hbm don dan life nhbdist h version nice b e dt xvg a r noda r2 abin rbin nonitacc contact shell fitstart fitstart temp smooth dump max_hb nomerge geminate diff acflen nonormalize P fitfn ncskip beginfit endfit" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-geminate]' -s " none dd ad aa a4" - 'c[-1,-P]' -s " 0 1 2 3" - 'c[-1,-fitfn]' -s " none exp aexp exp_exp vac exp5 exp7 exp9" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-num]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-g]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-ac]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-dist]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ang]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-hx]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-hbn]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-hbm]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-don]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-dan]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-life]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-nhbdist]' -g '*.xvg(|.gz|.Z) *(/)' -- g_hbond
+compctl  -x 's[-]' -s " f s n num g ac dist ang hx hbn hbm don dan life nhbdist h version nice b e dt tu xvg a r noda r2 abin rbin nonitacc contact shell fitstart fitstart temp smooth dump max_hb nomerge geminate diff acflen nonormalize P fitfn ncskip beginfit endfit" - 'c[-1,-tu]' -s " fs ps ns us ms s" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-geminate]' -s " none dd ad aa a4" - 'c[-1,-P]' -s " 0 1 2 3" - 'c[-1,-fitfn]' -s " none exp aexp exp_exp vac exp5 exp7 exp9 erffit" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-num]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-g]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-ac]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-dist]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ang]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-hx]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-hbn]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-hbm]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-don]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-dan]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-life]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-nhbdist]' -g '*.xvg(|.gz|.Z) *(/)' -- g_hbond
 compctl  -x 's[-]' -s " s n f to cz co h version nice b e dt w r0 q noF db prop ev ahxstart ahxend" - 'c[-1,-prop]' -s " RAD TWIST RISE LEN NHX DIP RMS CPHI RMSA PHI PSI HB3 HB4 HB5 CD222" - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-to]' -g '*.g87(|.gz|.Z) *(/)' - 'c[-1,-cz]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz)(|.gz|.Z) *(/)' - 'c[-1,-co]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz)(|.gz|.Z) *(/)' -- g_helix
 compctl  -x 's[-]' -s " s f n oaxis ocenter orise oradius otwist obending otilt orot h version nice b e dt xvg sidechain incremental" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-oaxis]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-ocenter]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-orise]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-oradius]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-otwist]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-obending]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-otilt]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-orot]' -g '*.xvg(|.gz|.Z) *(/)' -- g_helixorient
+compctl  -x 's[-]' -s " f n s o or Spect h version nice b e dt w d bw sgang1 sgang2 tblock nlevel" - 'c[-1,-d]' -s " z x y" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-or]' -g '*.out(|.gz|.Z) *(/)' - 'c[-1,-Spect]' -g '*.out(|.gz|.Z) *(/)' -- g_hydorder
+compctl  -x 's[-]' -s " f d d2 o o2 o3 ee g m h version nice tu w xvg notime b e bfit efit T n cut ucut euf efu ei maxiter noback tol skip nosplit nosum nodiscrete mult" - 'c[-1,-tu]' -s " fs ps ns us ms s" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-d]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-d2]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-o2]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-o3]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ee]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-g]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-m]' -g '*.xvg(|.gz|.Z) *(/)' -- g_kinetics
 compctl  -x 's[-]' -s " f o h version nice b e dt w xvg Elj Eqq Clj Cqq ligand" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.edr(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' -- g_lie
 compctl  -x 's[-]' -s " f s n mean frames no h version nice b e dt xvg t nlevels" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-mean]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-frames]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-no]' -g '*.xvg(|.gz|.Z) *(/)' -- g_mdmat
-compctl  -x 's[-]' -s " f n p o x cpi cpo c e g ei rerun table tablep tableb dhdl field table tablep tableb rerun tpi tpid ei eo j jo ffout devout runav px pf mtx dn h version nice deffnm xvg xyinit xyend zinit zend nxy nz rad pieces asymmetry ndiff maxwarn nocompact v" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-p]' -g '*.top(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.(trr|cpt|trj)(|.gz|.Z) *(/)' - 'c[-1,-x]' -g '*.xtc(|.gz|.Z) *(/)' - 'c[-1,-cpi]' -g '*.cpt(|.gz|.Z) *(/)' - 'c[-1,-cpo]' -g '*.cpt(|.gz|.Z) *(/)' - 'c[-1,-c]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz)(|.gz|.Z) *(/)' - 'c[-1,-e]' -g '*.edr(|.gz|.Z) *(/)' - 'c[-1,-g]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-ei]' -g '*.edi(|.gz|.Z) *(/)' - 'c[-1,-rerun]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-table]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-tablep]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-tableb]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-dhdl]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-field]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-table]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-tablep]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-tableb]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-rerun]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-tpi]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-tpid]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ei]' -g '*.edi(|.gz|.Z) *(/)' - 'c[-1,-eo]' -g '*.edo(|.gz|.Z) *(/)' - 'c[-1,-j]' -g '*.gct(|.gz|.Z) *(/)' - 'c[-1,-jo]' -g '*.gct(|.gz|.Z) *(/)' - 'c[-1,-ffout]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-devout]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-runav]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-px]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-pf]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-mtx]' -g '*.mtx(|.gz|.Z) *(/)' - 'c[-1,-dn]' -g '*.ndx(|.gz|.Z) *(/)' -- g_membed
+compctl  -x 's[-]' -s " f n p o x c e dat h version nice xyinit xyend zinit zend nxy nz rad pieces asymmetry ndiff maxwarn start v mdrun_path" - 'c[-1,-f]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-p]' -g '*.top(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.(trr|cpt|trj)(|.gz|.Z) *(/)' - 'c[-1,-x]' -g '*.xtc(|.gz|.Z) *(/)' - 'c[-1,-c]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz)(|.gz|.Z) *(/)' - 'c[-1,-e]' -g '*.edr(|.gz|.Z) *(/)' - 'c[-1,-dat]' -g '*.dat(|.gz|.Z) *(/)' -- g_membed
 compctl  -x 's[-]' -s " f s n od on o ox or h version nice b e dt tu w xvg matrix max d group pi split ng nopbc respertime printresname" - 'c[-1,-tu]' -s " fs ps ns us ms s" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-od]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-on]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.out(|.gz|.Z) *(/)' - 'c[-1,-ox]' -g '*.(xtc|trr|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-or]' -g '*.xvg(|.gz|.Z) *(/)' -- g_mindist
 compctl  -x 's[-]' -s " f1 f2 o or n h version nice w xvg ninterm first last nofit" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f1]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-f2]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-or]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' -- g_morph
 compctl  -x 's[-]' -s " f s n o mol pdb h version nice b e tu w xvg type lateral ten ngroup nomw rmcomm tpdb trestart beginfit endfit" - 'c[-1,-tu]' -s " fs ps ns us ms s" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-type]' -s " no x y z" - 'c[-1,-lateral]' -s " no x y z" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-mol]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-pdb]' -g '*.pdb(|.gz|.Z) *(/)' -- g_msd
-compctl  -x 's[-]' -s " f s of ol v h version nice xvg nom first last" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.mtx(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-of]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ol]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-v]' -g '*.(trr|cpt|trj)(|.gz|.Z) *(/)' -- g_nmeig
+compctl  -x 's[-]' -s " f f2 s1 s2 c e e2 n m h version nice vdwfac bonlo bonhi rmsd tol abstol ab lastener" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-f2]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s1]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-s2]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-c]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-e]' -g '*.edr(|.gz|.Z) *(/)' - 'c[-1,-e2]' -g '*.edr(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-m]' -g '*.tex(|.gz|.Z) *(/)' -- gmxcheck
+compctl  -x 's[-]' -s " s f e cp p mtx om h version nice nonr sys" - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-e]' -g '*.edr(|.gz|.Z) *(/)' - 'c[-1,-cp]' -g '*.cpt(|.gz|.Z) *(/)' - 'c[-1,-p]' -g '*.top(|.gz|.Z) *(/)' - 'c[-1,-mtx]' -g '*.mtx(|.gz|.Z) *(/)' - 'c[-1,-om]' -g '*.mdp(|.gz|.Z) *(/)' -- gmxdump
+compctl  -x 's[-]' -s " f s of ol os qc v h version nice xvg nom first last maxspec T constr width" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.mtx(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-of]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ol]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-os]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-qc]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-v]' -g '*.(trr|cpt|trj)(|.gz|.Z) *(/)' -- g_nmeig
 compctl  -x 's[-]' -s " v e s n o h version nice xvg temp seed num first last" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-v]' -g '*.(trr|cpt|trj)(|.gz|.Z) *(/)' - 'c[-1,-e]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.(xtc|trr|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' -- g_nmens
 compctl  -x 's[-]' -s " s v o h version nice eignr phases temp amplitude nframes" - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-v]' -g '*.(trr|cpt|trj)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.(xtc|trr|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' -- g_nmtraj
+compctl  -x 's[-]' -s " h version nice" -- g_options
 compctl  -x 's[-]' -s " f n nr s o od ob os Sg Sk Sgsl Sksl h version nice b e dt w xvg d sl szonly unsat permolecule radial calcdist" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-d]' -s " z x y" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-nr]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-od]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ob]' -g '*.pdb(|.gz|.Z) *(/)' - 'c[-1,-os]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-Sg]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-Sk]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-Sgsl]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-Sksl]' -g '*.xvg(|.gz|.Z) *(/)' -- g_order
+compctl  -x 's[-]' -s " s o so h version nice beta tune self seed v" - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.out(|.gz|.Z) *(/)' - 'c[-1,-so]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' -- g_pme_error
 compctl  -x 's[-]' -s " s f n o v p i h version nice b e dt tu w xvg nomw pc" - 'c[-1,-tu]' -s " fs ps ns us ms s" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-v]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-p]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-i]' -g '*.xvg(|.gz|.Z) *(/)' -- g_polystat
 compctl  -x 's[-]' -s " f n s o oc of h version nice b e dt w xvg d sl cb ce tz spherical ng correct" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-oc]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-of]' -g '*.xvg(|.gz|.Z) *(/)' -- g_potential
 compctl  -x 's[-]' -s " f s n a1 a2 a3 om h version nice b e dt tu w foo" - 'c[-1,-tu]' -s " fs ps ns us ms s" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-a1]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-a2]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-a3]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-om]' -g '*.dat(|.gz|.Z) *(/)' -- g_principal
@@ -49,11 +61,12 @@ compctl  -x 's[-]' -s " f s n d o sq cn hq h version nice b e dt w xvg bin com s
 compctl  -x 's[-]' -s " s f f2 n o mir a dist m bin bm h version nice b e dt tu w xvg what nopbc fit prev split skip skip2 max min bmax bmin nomw nlevels ng" - 'c[-1,-tu]' -s " fs ps ns us ms s" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-what]' -s " rmsd rho rhosc" - 'c[-1,-fit]' -s " rot+trans translation none" - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-f2]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-mir]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-a]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-dist]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-m]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-bin]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-bm]' -g '*.xpm(|.gz|.Z) *(/)' -- g_rms
 compctl  -x 's[-]' -s " f s n equiv o rms scl mean nmr3 nmr6 noe h version nice b e dt w xvg nlevels max nosumh nopbc" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-equiv]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-rms]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-scl]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-mean]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-nmr3]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-nmr6]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-noe]' -g '*.dat(|.gz|.Z) *(/)' -- g_rmsdist
 compctl  -x 's[-]' -s " f s n q oq ox o od oc dir h version nice b e dt w xvg res aniso nofit" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-q]' -g '*.pdb(|.gz|.Z) *(/)' - 'c[-1,-oq]' -g '*.pdb(|.gz|.Z) *(/)' - 'c[-1,-ox]' -g '*.pdb(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-od]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-oc]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-dir]' -g '*.log(|.gz|.Z) *(/)' -- g_rmsf
-compctl  -x 's[-]' -s " f s n o h version nice b e dt w xvg d noaver acflen nonormalize P fitfn ncskip beginfit endfit" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-P]' -s " 0 1 2 3" - 'c[-1,-fitfn]' -s " none exp aexp exp_exp vac exp5 exp7 exp9" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' -- g_rotacf
+compctl  -x 's[-]' -s " f po c r rb n p pp o t e ref h version nice v time normvsbds maxwarn zero norenum" - 'c[-1,-f]' -g '*.mdp(|.gz|.Z) *(/)' - 'c[-1,-po]' -g '*.mdp(|.gz|.Z) *(/)' - 'c[-1,-c]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-r]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-rb]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-p]' -g '*.top(|.gz|.Z) *(/)' - 'c[-1,-pp]' -g '*.top(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-t]' -g '*.(trr|cpt|trj)(|.gz|.Z) *(/)' - 'c[-1,-e]' -g '*.edr(|.gz|.Z) *(/)' - 'c[-1,-ref]' -g '*.(trr|cpt|trj)(|.gz|.Z) *(/)' -- grompp
+compctl  -x 's[-]' -s " f s n o h version nice b e dt w xvg d noaver acflen nonormalize P fitfn ncskip beginfit endfit" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-P]' -s " 0 1 2 3" - 'c[-1,-fitfn]' -s " none exp aexp exp_exp vac exp5 exp7 exp9 erffit" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' -- g_rotacf
 compctl  -x 's[-]' -s " f s n o h version nice b e dt w xvg ref skip fitxy nomw" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-ref]' -s " none xyz xy" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' -- g_rotmat
 compctl  -x 's[-]' -s " f s h version nice b e dt t sep" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' -- g_saltbr
+compctl  -x 's[-]' -s " s f n d pr sq prframe sqframe h version nice b e dt tu xvg mode mcover nopbc startq endq qstep seed" - 'c[-1,-tu]' -s " fs ps ns us ms s" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-mode]' -s " direct mc" - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-d]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-pr]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-sq]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-prframe]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-sqframe]' -g '*.xvg(|.gz|.Z) *(/)' -- g_sans
 compctl  -x 's[-]' -s " f s o or oa tv q n i h version nice b e dt w xvg probe ndots qmax f_index minarea nopbc noprot dgs" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-or]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-oa]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-tv]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-q]' -g '*.pdb(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-i]' -g '*.itp(|.gz|.Z) *(/)' -- g_sas
-compctl  -x 's[-]' -s " f n s o r h version nice b e dt mode triangle dtri bin grid" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-r]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz)(|.gz|.Z) *(/)' -- g_sdf
 compctl  -x 's[-]' -s " f s sf n os oc oi om on h version nice b e dt xvg normpbc nopbc select selrpos seltype dump norm cfnorm resnr" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-selrpos]' -s " atom res_com res_cog mol_com mol_cog whole_res_com whole_res_cog whole_mol_com whole_mol_cog part_res_com part_res_cog part_mol_com part_mol_cog dyn_res_com dyn_res_cog dyn_mol_com dyn_mol_cog" - 'c[-1,-seltype]' -s " atom res_com res_cog mol_com mol_cog whole_res_com whole_res_cog whole_mol_com whole_mol_cog part_res_com part_res_cog part_mol_com part_mol_cog dyn_res_com dyn_res_cog dyn_mol_com dyn_mol_cog" - 'c[-1,-resnr]' -s " number index" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-sf]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-os]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-oc]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-oi]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-om]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-on]' -g '*.ndx(|.gz|.Z) *(/)' -- g_select
 compctl  -x 's[-]' -s " f n s oa od od1 od2 h version nice b e dt w xvg one z" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-oa]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-od]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-od1]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-od2]' -g '*.xvg(|.gz|.Z) *(/)' -- g_sgangle
 compctl  -x 's[-]' -s " f ge ene dist histo bin lp ls lsh lss map ls3 mdata g h version nice w xvg notime b e ttol n d bw nosham tsham pmin dim ngrid xmin xmax pmax gmax emin emax nlevels mname" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ge]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ene]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-dist]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-histo]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-bin]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-lp]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-ls]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-lsh]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-lss]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-map]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-ls3]' -g '*.pdb(|.gz|.Z) *(/)' - 'c[-1,-mdata]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-g]' -g '*.log(|.gz|.Z) *(/)' -- g_sham
@@ -61,30 +74,24 @@ compctl  -x 's[-]' -s " o h version nice w xvg c6 cn pow sig eps A B C qi qj sig
 compctl  -x 's[-]' -s " f s n o no ro co rc h version nice b e dt w xvg com v23 rmin rmax cbin rbin pbc" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-no]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ro]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-co]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-rc]' -g '*.xvg(|.gz|.Z) *(/)' -- g_sorient
 compctl  -x 's[-]' -s " s f n h version nice b e dt w pbc nodiv ign bin nab" - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' -- g_spatial
 compctl  -x 's[-]' -s " f s n o h version nice b e dt w xvg com refat rmin rmax dip bw" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' -- g_spol
-compctl  -x 's[-]' -s " f s n ot oa o of oc ov h version nice b e dt w xvg mol k34 wt acflen nonormalize P fitfn ncskip beginfit endfit" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-P]' -s " 0 1 2 3" - 'c[-1,-fitfn]' -s " none exp aexp exp_exp vac exp5 exp7 exp9" - 'c[-1,-f]' -g '*.(trr|cpt|trj)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-ot]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-oa]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-of]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-oc]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ov]' -g '*.xvg(|.gz|.Z) *(/)' -- g_tcaf
-compctl  -x 's[-]' -s " f s n ox oxt ov of ob ot ekt ekr vd cv cf av af h version nice b e dt tu w xvg com nopbc mol nojump nox noy noz ng len fp bin scale" - 'c[-1,-tu]' -s " fs ps ns us ms s" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-ox]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-oxt]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-ov]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-of]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ob]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ot]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ekt]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ekr]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-vd]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-cv]' -g '*.pdb(|.gz|.Z) *(/)' - 'c[-1,-cf]' -g '*.pdb(|.gz|.Z) *(/)' - 'c[-1,-av]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-af]' -g '*.xvg(|.gz|.Z) *(/)' -- g_traj
-compctl  -x 's[-]' -s " p err so s o x cpi cpo c e g dhdl field table tablep tableb rerun tpi tpid ei eo j jo ffout devout runav px pf mtx dn bo bx bcpo bc be bg beo bdhdl bfield btpi btpid bjo bffout bdevout brunav bpx bpf bmtx bdn h version nice xvg np npstring nt r max min npme upfac downfac ntpr four steps resetstep simsteps launch deffnm ddorder noddcheck rdd rcon dlb dds gcom v nocompact seppot pforce reprod cpt cpnum noappend maxh multi replex reseed ionize" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-npstring]' -s " -np -n none" - 'c[-1,-npme]' -s " auto all subset" - 'c[-1,-ddorder]' -s " interleave pp_pme cartesian" - 'c[-1,-dlb]' -s " auto no yes" - 'c[-1,-p]' -g '*.out(|.gz|.Z) *(/)' - 'c[-1,-err]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-so]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.(trr|cpt|trj)(|.gz|.Z) *(/)' - 'c[-1,-x]' -g '*.xtc(|.gz|.Z) *(/)' - 'c[-1,-cpi]' -g '*.cpt(|.gz|.Z) *(/)' - 'c[-1,-cpo]' -g '*.cpt(|.gz|.Z) *(/)' - 'c[-1,-c]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz)(|.gz|.Z) *(/)' - 'c[-1,-e]' -g '*.edr(|.gz|.Z) *(/)' - 'c[-1,-g]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-dhdl]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-field]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-table]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-tablep]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-tableb]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-rerun]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-tpi]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-tpid]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ei]' -g '*.edi(|.gz|.Z) *(/)' - 'c[-1,-eo]' -g '*.edo(|.gz|.Z) *(/)' - 'c[-1,-j]' -g '*.gct(|.gz|.Z) *(/)' - 'c[-1,-jo]' -g '*.gct(|.gz|.Z) *(/)' - 'c[-1,-ffout]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-devout]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-runav]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-px]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-pf]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-mtx]' -g '*.mtx(|.gz|.Z) *(/)' - 'c[-1,-dn]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-bo]' -g '*.(trr|cpt|trj)(|.gz|.Z) *(/)' - 'c[-1,-bx]' -g '*.xtc(|.gz|.Z) *(/)' - 'c[-1,-bcpo]' -g '*.cpt(|.gz|.Z) *(/)' - 'c[-1,-bc]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz)(|.gz|.Z) *(/)' - 'c[-1,-be]' -g '*.edr(|.gz|.Z) *(/)' - 'c[-1,-bg]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-beo]' -g '*.edo(|.gz|.Z) *(/)' - 'c[-1,-bdhdl]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-bfield]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-btpi]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-btpid]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-bjo]' -g '*.gct(|.gz|.Z) *(/)' - 'c[-1,-bffout]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-bdevout]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-brunav]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-bpx]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-bpf]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-bmtx]' -g '*.mtx(|.gz|.Z) *(/)' - 'c[-1,-bdn]' -g '*.ndx(|.gz|.Z) *(/)' -- g_tune_pme
+compctl  -x 's[-]' -s " f s n ot oa o of oc ov h version nice b e dt w xvg mol k34 wt acflen nonormalize P fitfn ncskip beginfit endfit" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-P]' -s " 0 1 2 3" - 'c[-1,-fitfn]' -s " none exp aexp exp_exp vac exp5 exp7 exp9 erffit" - 'c[-1,-f]' -g '*.(trr|cpt|trj)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-ot]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-oa]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-of]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-oc]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ov]' -g '*.xvg(|.gz|.Z) *(/)' -- g_tcaf
+compctl  -x 's[-]' -s " f s n ox oxt ov of ob ot ekt ekr vd cv cf av af h version nice b e dt tu w xvg com nopbc mol nojump nox noy noz ng len fp bin ctime scale" - 'c[-1,-tu]' -s " fs ps ns us ms s" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-ox]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-oxt]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-ov]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-of]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ob]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ot]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ekt]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ekr]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-vd]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-cv]' -g '*.pdb(|.gz|.Z) *(/)' - 'c[-1,-cf]' -g '*.pdb(|.gz|.Z) *(/)' - 'c[-1,-av]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-af]' -g '*.xvg(|.gz|.Z) *(/)' -- g_traj
+compctl  -x 's[-]' -s " p err so s o x cpi cpo c e g dhdl field table tabletf tablep tableb rerun tpi tpid ei eo j jo ffout devout runav px pf ro ra rs rt mtx dn bo bx bcpo bc be bg beo bdhdl bfield btpi btpid bjo bffout bdevout brunav bpx bpf bro bra brs brt bmtx bdn h version nice xvg np npstring ntmpi r max min npme fix rmax rmin noscalevdw ntpr steps resetstep simsteps launch nobench noappend cpnum" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-npstring]' -s " -np -n none" - 'c[-1,-npme]' -s " auto all subset" - 'c[-1,-p]' -g '*.out(|.gz|.Z) *(/)' - 'c[-1,-err]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-so]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.(trr|cpt|trj)(|.gz|.Z) *(/)' - 'c[-1,-x]' -g '*.xtc(|.gz|.Z) *(/)' - 'c[-1,-cpi]' -g '*.cpt(|.gz|.Z) *(/)' - 'c[-1,-cpo]' -g '*.cpt(|.gz|.Z) *(/)' - 'c[-1,-c]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz)(|.gz|.Z) *(/)' - 'c[-1,-e]' -g '*.edr(|.gz|.Z) *(/)' - 'c[-1,-g]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-dhdl]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-field]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-table]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-tabletf]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-tablep]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-tableb]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-rerun]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-tpi]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-tpid]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ei]' -g '*.edi(|.gz|.Z) *(/)' - 'c[-1,-eo]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-j]' -g '*.gct(|.gz|.Z) *(/)' - 'c[-1,-jo]' -g '*.gct(|.gz|.Z) *(/)' - 'c[-1,-ffout]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-devout]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-runav]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-px]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-pf]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ro]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ra]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-rs]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-rt]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-mtx]' -g '*.mtx(|.gz|.Z) *(/)' - 'c[-1,-dn]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-bo]' -g '*.(trr|cpt|trj)(|.gz|.Z) *(/)' - 'c[-1,-bx]' -g '*.xtc(|.gz|.Z) *(/)' - 'c[-1,-bcpo]' -g '*.cpt(|.gz|.Z) *(/)' - 'c[-1,-bc]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz)(|.gz|.Z) *(/)' - 'c[-1,-be]' -g '*.edr(|.gz|.Z) *(/)' - 'c[-1,-bg]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-beo]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-bdhdl]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-bfield]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-btpi]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-btpid]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-bjo]' -g '*.gct(|.gz|.Z) *(/)' - 'c[-1,-bffout]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-bdevout]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-brunav]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-bpx]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-bpf]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-bro]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-bra]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-brs]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-brt]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-bmtx]' -g '*.mtx(|.gz|.Z) *(/)' - 'c[-1,-bdn]' -g '*.ndx(|.gz|.Z) *(/)' -- g_tune_pme
 compctl  -x 's[-]' -s " f s n om or ot h version nice b e dt w xvg sqrt fm rmax rbin mmax nlevels nr fr rt ft" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-om]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-or]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ot]' -g '*.xvg(|.gz|.Z) *(/)' -- g_vanhove
-compctl  -x 's[-]' -s " f s n o h version nice b e dt w xvg m mol acflen nonormalize P fitfn ncskip beginfit endfit" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-P]' -s " 0 1 2 3" - 'c[-1,-fitfn]' -s " none exp aexp exp_exp vac exp5 exp7 exp9" - 'c[-1,-f]' -g '*.(trr|cpt|trj)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' -- g_velacc
-compctl  -x 's[-]' -s " ix if it ip o hist bsres bsprof tab wcorr h version nice xvg min max noauto bins temp tol v b e dt histonly boundsonly nolog unit zprof0 cycl alpha flip hist-eq nBootstrap bs-dt bs-seed nohistbs histbs-block vbs" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-unit]' -s " kJ kCal kT" - 'c[-1,-cycl]' -s " no yes weighted" - 'c[-1,-ix]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-if]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-it]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-ip]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-hist]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-bsres]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-bsprof]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-tab]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-wcorr]' -g '*.xvg(|.gz|.Z) *(/)' -- g_wham
+compctl  -x 's[-]' -s " f s n o os h version nice b e dt w xvg m norecip mol acflen nonormalize P fitfn ncskip beginfit endfit" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-P]' -s " 0 1 2 3" - 'c[-1,-fitfn]' -s " none exp aexp exp_exp vac exp5 exp7 exp9 erffit" - 'c[-1,-f]' -g '*.(trr|cpt|trj)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-os]' -g '*.xvg(|.gz|.Z) *(/)' -- g_velacc
+compctl  -x 's[-]' -s " ix if it ip o hist oiact iiact bsres bsprof tab h version nice xvg min max noauto bins temp tol v b e dt histonly boundsonly nolog unit zprof0 cycl sym ac acsig ac-trestart nBootstrap bs-method bs-tau bs-seed histbs-block vbs" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-unit]' -s " kJ kCal kT" - 'c[-1,-bs-method]' -s " b-hist hist traj traj-gauss" - 'c[-1,-ix]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-if]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-it]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-ip]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-hist]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-oiact]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-iiact]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-bsres]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-bsprof]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-tab]' -g '*.dat(|.gz|.Z) *(/)' -- g_wham
 compctl  -x 's[-]' -s " f o h version nice r0 rot0 T nonn" - 'c[-1,-f]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.eps(|.gz|.Z) *(/)' -- g_wheel
 compctl  -x 's[-]' -s " f o r h version nice ff v nexcl noH14 alldih remdih nopairs name nopbc pdbq noparam noround kb kt kp" - 'c[-1,-f]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.top(|.gz|.Z) *(/)' - 'c[-1,-r]' -g '*.rtp(|.gz|.Z) *(/)' -- g_x2top
 compctl  -x 's[-]' -s " f s h version nice b e dt" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' -- g_xrama
-compctl  -x 's[-]' -s " cp cs ci o p h version nice box nmol try seed vdwd shell maxsol vel" - 'c[-1,-cp]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-cs]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-ci]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz)(|.gz|.Z) *(/)' - 'c[-1,-p]' -g '*.top(|.gz|.Z) *(/)' -- genbox
-compctl  -x 's[-]' -s " f o trj h version nice nbox dist seed rot shuffle sort block nmolat maxrot norenumber" - 'c[-1,-f]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz)(|.gz|.Z) *(/)' - 'c[-1,-trj]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' -- genconf
-compctl  -x 's[-]' -s " s table n o g pot p h version nice xvg np pname pq nn nname nq rmin norandom seed scale conc neutral" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-table]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz)(|.gz|.Z) *(/)' - 'c[-1,-g]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-pot]' -g '*.pdb(|.gz|.Z) *(/)' - 'c[-1,-p]' -g '*.top(|.gz|.Z) *(/)' -- genion
-compctl  -x 's[-]' -s " f n o of h version nice fc freeze disre disre_dist disre_frac disre_up2 cutoff constr" - 'c[-1,-f]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.itp(|.gz|.Z) *(/)' - 'c[-1,-of]' -g '*.ndx(|.gz|.Z) *(/)' -- genrestr
-compctl  -x 's[-]' -s " f f2 s1 s2 c e e2 n m h version nice vdwfac bonlo bonhi rmsd tol abstol ab lastener" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-f2]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s1]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-s2]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-c]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-e]' -g '*.edr(|.gz|.Z) *(/)' - 'c[-1,-e2]' -g '*.edr(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-m]' -g '*.tex(|.gz|.Z) *(/)' -- gmxcheck
-compctl  -x 's[-]' -s " s f e cp p mtx om h version nice nonr sys" - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-e]' -g '*.edr(|.gz|.Z) *(/)' - 'c[-1,-cp]' -g '*.cpt(|.gz|.Z) *(/)' - 'c[-1,-p]' -g '*.top(|.gz|.Z) *(/)' - 'c[-1,-mtx]' -g '*.mtx(|.gz|.Z) *(/)' - 'c[-1,-om]' -g '*.mdp(|.gz|.Z) *(/)' -- gmxdump
-compctl  -x 's[-]' -s " f po c r rb n p pp o t e h version nice v time normvsbds maxwarn zero norenum" - 'c[-1,-f]' -g '*.mdp(|.gz|.Z) *(/)' - 'c[-1,-po]' -g '*.mdp(|.gz|.Z) *(/)' - 'c[-1,-c]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-r]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-rb]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-p]' -g '*.top(|.gz|.Z) *(/)' - 'c[-1,-pp]' -g '*.top(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-t]' -g '*.(trr|cpt|trj)(|.gz|.Z) *(/)' - 'c[-1,-e]' -g '*.edr(|.gz|.Z) *(/)' -- grompp
-compctl  -x 's[-]' -s " f eig s n tar ori o h version nice xvg mon linfix linacc flood radfix radacc radcon outfrq slope maxedsteps deltaF0 deltaF tau eqsteps Eflnull T alpha linstep accdir radstep restrain hessian harmonic" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.(trr|cpt|trj)(|.gz|.Z) *(/)' - 'c[-1,-eig]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-tar]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-ori]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.edi(|.gz|.Z) *(/)' -- make_edi
+compctl  -x 's[-]' -s " f eig s n tar ori o h version nice xvg mon linfix linacc radfix radacc radcon flood outfrq slope linstep accdir radstep maxedsteps eqsteps deltaF0 deltaF tau Eflnull T alpha restrain hessian harmonic constF" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.(trr|cpt|trj)(|.gz|.Z) *(/)' - 'c[-1,-eig]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-tar]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-ori]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.edi(|.gz|.Z) *(/)' -- make_edi
 compctl  -x 's[-]' -s " f n o h version nice natoms" - 'c[-1,-f]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.ndx(|.gz|.Z) *(/)' -- make_ndx
-compctl  -x 's[-]' -s " s o x cpi cpo c e g dhdl field table tablep tableb rerun tpi tpid ei eo j jo ffout devout runav px pf mtx dn h version nice deffnm xvg pd dd nt npme ddorder noddcheck rdd rcon dlb dds gcom v nocompact seppot pforce reprod cpt cpnum noappend maxh multi replex reseed ionize" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-ddorder]' -s " interleave pp_pme cartesian" - 'c[-1,-dlb]' -s " auto no yes" - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.(trr|cpt|trj)(|.gz|.Z) *(/)' - 'c[-1,-x]' -g '*.xtc(|.gz|.Z) *(/)' - 'c[-1,-cpi]' -g '*.cpt(|.gz|.Z) *(/)' - 'c[-1,-cpo]' -g '*.cpt(|.gz|.Z) *(/)' - 'c[-1,-c]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz)(|.gz|.Z) *(/)' - 'c[-1,-e]' -g '*.edr(|.gz|.Z) *(/)' - 'c[-1,-g]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-dhdl]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-field]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-table]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-tablep]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-tableb]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-rerun]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-tpi]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-tpid]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ei]' -g '*.edi(|.gz|.Z) *(/)' - 'c[-1,-eo]' -g '*.edo(|.gz|.Z) *(/)' - 'c[-1,-j]' -g '*.gct(|.gz|.Z) *(/)' - 'c[-1,-jo]' -g '*.gct(|.gz|.Z) *(/)' - 'c[-1,-ffout]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-devout]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-runav]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-px]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-pf]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-mtx]' -g '*.mtx(|.gz|.Z) *(/)' - 'c[-1,-dn]' -g '*.ndx(|.gz|.Z) *(/)' -- mdrun
+compctl  -x 's[-]' -s " s o x cpi cpo c e g dhdl field table tabletf tablep tableb rerun tpi tpid ei eo j jo ffout devout runav px pf ro ra rs rt mtx dn multidir membed mp mn h version nice deffnm xvg pd dd ddorder npme nt ntmpi ntomp ntomp_pme nopin pinht pinoffset gpu_id noddcheck rdd rcon dlb dds gcom nb notunepme testverlet v nocompact seppot pforce reprod cpt cpnum noappend nsteps maxh multi replex nex reseed ionize" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-ddorder]' -s " interleave pp_pme cartesian" - 'c[-1,-dlb]' -s " auto no yes" - 'c[-1,-nb]' -s " auto cpu gpu gpu_cpu" - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.(trr|cpt|trj)(|.gz|.Z) *(/)' - 'c[-1,-x]' -g '*.xtc(|.gz|.Z) *(/)' - 'c[-1,-cpi]' -g '*.cpt(|.gz|.Z) *(/)' - 'c[-1,-cpo]' -g '*.cpt(|.gz|.Z) *(/)' - 'c[-1,-c]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz)(|.gz|.Z) *(/)' - 'c[-1,-e]' -g '*.edr(|.gz|.Z) *(/)' - 'c[-1,-g]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-dhdl]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-field]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-table]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-tabletf]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-tablep]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-tableb]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-rerun]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-tpi]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-tpid]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ei]' -g '*.edi(|.gz|.Z) *(/)' - 'c[-1,-eo]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-j]' -g '*.gct(|.gz|.Z) *(/)' - 'c[-1,-jo]' -g '*.gct(|.gz|.Z) *(/)' - 'c[-1,-ffout]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-devout]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-runav]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-px]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-pf]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ro]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ra]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-rs]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-rt]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-mtx]' -g '*.mtx(|.gz|.Z) *(/)' - 'c[-1,-dn]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-multidir]' -g '*.rundir(|.gz|.Z) *(/)' - 'c[-1,-membed]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-mp]' -g '*.top(|.gz|.Z) *(/)' - 'c[-1,-mn]' -g '*.ndx(|.gz|.Z) *(/)' -- mdrun
+compctl  -x 's[-]' -s " s o x cpi cpo c e g dhdl field table tabletf tablep tableb rerun tpi tpid ei eo j jo ffout devout runav px pf ro ra rs rt mtx dn multidir membed mp mn h version nice deffnm xvg pd dd ddorder npme nt ntmpi ntomp ntomp_pme nopin pinht pinoffset gpu_id noddcheck rdd rcon dlb dds gcom nb notunepme testverlet v nocompact seppot pforce reprod cpt cpnum noappend nsteps maxh multi replex nex reseed ionize" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-ddorder]' -s " interleave pp_pme cartesian" - 'c[-1,-dlb]' -s " auto no yes" - 'c[-1,-nb]' -s " auto cpu gpu gpu_cpu" - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.(trr|cpt|trj)(|.gz|.Z) *(/)' - 'c[-1,-x]' -g '*.xtc(|.gz|.Z) *(/)' - 'c[-1,-cpi]' -g '*.cpt(|.gz|.Z) *(/)' - 'c[-1,-cpo]' -g '*.cpt(|.gz|.Z) *(/)' - 'c[-1,-c]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz)(|.gz|.Z) *(/)' - 'c[-1,-e]' -g '*.edr(|.gz|.Z) *(/)' - 'c[-1,-g]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-dhdl]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-field]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-table]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-tabletf]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-tablep]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-tableb]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-rerun]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-tpi]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-tpid]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ei]' -g '*.edi(|.gz|.Z) *(/)' - 'c[-1,-eo]' -g '*.edo(|.gz|.Z) *(/)' - 'c[-1,-j]' -g '*.gct(|.gz|.Z) *(/)' - 'c[-1,-jo]' -g '*.gct(|.gz|.Z) *(/)' - 'c[-1,-ffout]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-devout]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-runav]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-px]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-pf]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ro]' -g '*.xvg(|.gz|.Z) *(/)' - 'c[-1,-ra]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-rs]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-rt]' -g '*.log(|.gz|.Z) *(/)' - 'c[-1,-mtx]' -g '*.mtx(|.gz|.Z) *(/)' - 'c[-1,-dn]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-multidir]' -g '*.rundir(|.gz|.Z) *(/)' - 'c[-1,-membed]' -g '*.dat(|.gz|.Z) *(/)' - 'c[-1,-mp]' -g '*.top(|.gz|.Z) *(/)' - 'c[-1,-mn]' -g '*.ndx(|.gz|.Z) *(/)' -- mdrun_mpi
 compctl  -x 's[-]' -s " s n h version nice type nohyd hq" - 'c[-1,-type]' -s " angle dihedral improper ryckaert-bellemans" - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' -- mk_angndx
 compctl  -x 's[-]' -s " f s n h version nice b e dt" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' -- ngmx
-compctl  -x 's[-]' -s " f o p i n q h version nice chainsep ff water inter ss ter lys arg asp glu gln his angle dist una ignh missing v posrefc vsite heavyh deuterate nochargegrp nocmap renum rtpres" - 'c[-1,-chainsep]' -s " id_or_ter id_and_ter ter id interactive" - 'c[-1,-water]' -s " select none spc spce tip3p tip4p tip5p" - 'c[-1,-vsite]' -s " none hydrogens aromatics" - 'c[-1,-f]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz)(|.gz|.Z) *(/)' - 'c[-1,-p]' -g '*.top(|.gz|.Z) *(/)' - 'c[-1,-i]' -g '*.itp(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-q]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz)(|.gz|.Z) *(/)' -- pdb2gmx
-compctl  -x 's[-]' -s " s f e n o h version nice extend until nsteps time zeroq novel nocont" - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-f]' -g '*.(trr|cpt|trj)(|.gz|.Z) *(/)' - 'c[-1,-e]' -g '*.edr(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' -- tpbconv
+compctl  -x 's[-]' -s " f o p i n q h version nice chainsep merge ff water inter ss ter lys arg asp glu gln his angle dist una ignh missing v posrefc vsite heavyh deuterate nochargegrp nocmap renum rtpres" - 'c[-1,-chainsep]' -s " id_or_ter id_and_ter ter id interactive" - 'c[-1,-merge]' -s " no all interactive" - 'c[-1,-water]' -s " select none spc spce tip3p tip4p tip5p" - 'c[-1,-vsite]' -s " none hydrogens aromatics" - 'c[-1,-f]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz|tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz)(|.gz|.Z) *(/)' - 'c[-1,-p]' -g '*.top(|.gz|.Z) *(/)' - 'c[-1,-i]' -g '*.itp(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-q]' -g '*.(gro|g96|pdb|brk|ent|esp|xyz)(|.gz|.Z) *(/)' -- pdb2gmx
+compctl  -x 's[-]' -s " s f e n o h version nice extend until nsteps time zeroq novel nocont init_fep_state" - 'c[-1,-s]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' - 'c[-1,-f]' -g '*.(trr|cpt|trj)(|.gz|.Z) *(/)' - 'c[-1,-e]' -g '*.edr(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.(tpr|tpb|tpa)(|.gz|.Z) *(/)' -- tpbconv
 compctl  -x 's[-]' -s " f o n demux h version nice tu xvg b e dt prec novel settime nosort keeplast overwrite cat" - 'c[-1,-tu]' -s " fs ps ns us ms s" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.(xtc|trr|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-demux]' -g '*.xvg(|.gz|.Z) *(/)' -- trjcat
-compctl  -x 's[-]' -s " f o s n fr sub drop h version nice b e tu w xvg skip dt round dump t0 timestep pbc ur center boxcenter box trans shift fit ndec novel force trunc exec app split sep nzero dropunder dropover conect" - 'c[-1,-tu]' -s " fs ps ns us ms s" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-pbc]' -s " none mol res atom nojump cluster whole" - 'c[-1,-ur]' -s " rect tric compact" - 'c[-1,-boxcenter]' -s " tric rect zero" - 'c[-1,-fit]' -s " none rot+trans rotxy+transxy translation transxy progressive" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.(xtc|trr|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-fr]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-sub]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-drop]' -g '*.xvg(|.gz|.Z) *(/)' -- trjconv
+compctl  -x 's[-]' -s " f o s n fr sub drop h version nice b e tu w xvg skip dt round dump t0 timestep pbc ur center boxcenter box clustercenter trans shift fit ndec novel force trunc exec app split sep nzero dropunder dropover conect" - 'c[-1,-tu]' -s " fs ps ns us ms s" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-pbc]' -s " none mol res atom nojump cluster whole" - 'c[-1,-ur]' -s " rect tric compact" - 'c[-1,-boxcenter]' -s " tric rect zero" - 'c[-1,-fit]' -s " none rot+trans rotxy+transxy translation transxy progressive" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.(xtc|trr|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-fr]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-sub]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-drop]' -g '*.xvg(|.gz|.Z) *(/)' -- trjconv
 compctl  -x 's[-]' -s " f s n o nshell h version nice b e dt xvg na da com r z" - 'c[-1,-xvg]' -s " xmgrace xmgr none" - 'c[-1,-f]' -g '*.(xtc|trr|cpt|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-s]' -g '*.(tpr|tpb|tpa|gro|g96|pdb|brk|ent)(|.gz|.Z) *(/)' - 'c[-1,-n]' -g '*.ndx(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.(xtc|trr|trj|gro|g96|pdb|g87)(|.gz|.Z) *(/)' - 'c[-1,-nshell]' -g '*.xvg(|.gz|.Z) *(/)' -- trjorder
 compctl  -x 's[-]' -s " f f2 di do o xpm h version nice w noframe title yonce legend diag size bx by rainbow gradient skip zeroline legoffset combine cmin cmax" - 'c[-1,-title]' -s " top once ylabel none" - 'c[-1,-legend]' -s " both first second none" - 'c[-1,-diag]' -s " first second none" - 'c[-1,-rainbow]' -s " no blue red" - 'c[-1,-combine]' -s " halves add sub mult div" - 'c[-1,-f]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-f2]' -g '*.xpm(|.gz|.Z) *(/)' - 'c[-1,-di]' -g '*.m2p(|.gz|.Z) *(/)' - 'c[-1,-do]' -g '*.m2p(|.gz|.Z) *(/)' - 'c[-1,-o]' -g '*.eps(|.gz|.Z) *(/)' - 'c[-1,-xpm]' -g '*.xpm(|.gz|.Z) *(/)' -- xpm2ps
index b15510e463173d0c6991c9ee1b32641a3827bbc4..86adb78f147103372c740579dc99d59e69d7a8c3 100644 (file)
@@ -1491,54 +1491,62 @@ The potentials, bond-lengths and angles are interpolated linearly as
 described in the manual. When <b>sc-alpha</b> is larger than zero, soft-core
 potentials are used for the LJ and Coulomb interactions.</dd>
 </dl></dd>
-<dt><b>init-lambda: (0)</b></dt>
-<dd>starting value for lambda (float).  Generally, this should only be used with slow growth.  In other cases, <b>init-lambda-state</b> should be specified instead.</dd>
-<dt><b>init-lambda-state: (0)</b></dt>
-<dd>starting value for the lambda state (integer).  Specified which columm of the lambda vector should be used.</dd>
+<dt><b>init-lambda: (-1)</b></dt>
+<dd>starting value for lambda (float).  Generally, this should only be used with slow growth (i.e. nonzero <b>delta-lambda</b>).  In other cases, <b>init-lambda-state</b> should be specified instead. Must be greater than or equal to 0.</dd>
 <dt><b>delta-lambda: (0)</b></dt>
 <dd>increment per time step for lambda</dd>
+<dt><b>init-lambda-state: (-1)</b></dt>
+<dd>starting value for the lambda state (integer).  Specifies which columm of the lambda vector (<b>coul-lambdas</b>, <b>vdw-lambdas</b>, <b>bonded-lambdas</b>, <b>restraint-lambdas</b>, <b>mass-lambdas</b>, <b>temperature-lambdas</b>, <b>fep-lambdas</b>) should be used. This is a zero-based index: <b>init-lambda-state</b> 0 means the first column, and so on.</dd>
 <dt><b>fep-lambdas: ()</b></dt>
 <dd>Zero, one or more lambda values for which Delta H values will
-be determined and written to dhdl.xvg every <b>nstdhdl</b> steps.
+be determined and written to dhdl.xvg every <b>nstdhdl</b> steps. 
+Values must be between 0 and 1.
 Free energy differences between different lambda values can then
 be determined with <tt>g_bar</tt>. <b>fep-lambdas</b> is different from the other -lambdas keywords because
-all components of the lambda vector that are not specified will use <b>fep-lambdas</b>.</dd>
+all components of the lambda vector that are not specified will use <b>fep-lambdas</b> (including restraint-lambdas and therefore the pull code restraints).</dd>
 <dt><b>coul-lambdas: ()</b></dt>
 <dd>Zero, one or more lambda values for which Delta H values will
-be determined and written to dhdl.xvg every <b>nstdhdl</b> steps.
-Only the electrostatic interactions are controlled with this component of the lambda vector.</dd>
+be determined and written to dhdl.xvg every <b>nstdhdl</b> steps. Values must be between 0 and 1.
+Only the electrostatic interactions are controlled with this component of the lambda vector (and only if the lambda=0 and lambda=1 states have differing electrostatic interactions).</dd>
 <dt><b>vdw-lambdas: ()</b></dt>
 <dd>Zero, one or more lambda values for which Delta H values will
-be determined and written to dhdl.xvg every <b>nstdhdl</b> steps.
+be determined and written to dhdl.xvg every <b>nstdhdl</b> steps. Values must be between 0 and 1.
 Only the van der Waals interactions are controlled with this component of the lambda vector.</dd>
 <dt><b>bonded-lambdas: ()</b></dt>
 <dd>Zero, one or more lambda values for which Delta H values will
-be determined and written to dhdl.xvg every <b>nstdhdl</b> steps.
+be determined and written to dhdl.xvg every <b>nstdhdl</b> steps. Values must be between 0 and 1.
 Only the bonded interactions are controlled with this component of the lambda vector.</dd>
 <dt><b>restraint-lambdas: ()</b></dt>
 <dd>Zero, one or more lambda values for which Delta H values will
-be determined and written to dhdl.xvg every <b>nstdhdl</b> steps.
-Only the restraint interactions are controlled with this component of the lambda vector.</dd>
+be determined and written to dhdl.xvg every <b>nstdhdl</b> steps. Values must be between 0 and 1.
+Only the restraint interactions: dihedral restraints, and the pull code restraints are controlled with this component of the lambda vector. </dd>
 <dt><b>mass-lambdas: ()</b></dt>
 <dd>Zero, one or more lambda values for which Delta H values will
-be determined and written to dhdl.xvg every <b>nstdhdl</b> steps.
+be determined and written to dhdl.xvg every <b>nstdhdl</b> steps. Values must be between 0 and 1.
 Only the particle masses are controlled with this component of the lambda vector.</dd>
 <dt><b>temperature-lambdas: ()</b></dt>
 <dd>Zero, one or more lambda values for which Delta H values will
-be determined and written to dhdl.xvg every <b>nstdhdl</b> steps.
+be determined and written to dhdl.xvg every <b>nstdhdl</b> steps. Values must be between 0 and 1.
 Only the temperatures controlled with this component of the lambda vector.
 Note that these lambdas should not be used for replica exchange, only for simulated tempering.</dd>
+<dt><b>calc-lambda-neighbors (1)</b></dt>
+<dd>Controls the number of lambda values for which Delta H values will be
+calculated and written out, if <b>init-lambda-state</b> has been set. A
+positive value will limit the number of lambda points calculated to only the
+nth neighbors of <b>init-lambda-state</b>: for example, if
+<b>init-lambda-state</b> is 5 and this parameter has a value of 2, energies for
+lambda points 3-7 will be calculated and writen out. A value of -1 means all
+lambda points will be written out. For normal BAR such as with g_bar, a value
+of 1 is sufficient, while for MBAR -1 should be used.</dd>
 <dt><b>sc-alpha: (0)</b></dt>
-<dd>the soft-core parameter, a value of 0 results in linear interpolation of
-the LJ and Coulomb interactions</dd>
+<dd>the soft-core alpha parameter, a value of 0 results in linear interpolation of the LJ and Coulomb interactions</dd>
 <dt><b>sc-r-power: (6)</b></dt>
 <dd>the power of the radial term in the soft-core equation.  Possible values are 6 and 48. 6 is more standard, and is the default.  When 48 is used, then sc-alpha should generally be much lower (between 0.001 and 0.003).</dd>
 <dt><b>sc-coul: (no)</b></dt>
 <dd>Whether to apply the soft core free energy interations to the Columbic interaction. Default is no, as it is generally
 more efficient to turn of the Coulomic interactions linearly before turning off electrostatic interactions.</dd>
 <dt><b>sc-power: (0)</b></dt>
-<dd>the power for lambda in the soft-core function,
-only the values 1 and 2 are supported</dd>
+<dd>the power for lambda in the soft-core function, only the values 1 and 2 are supported</dd>
 <dt><b>sc-sigma: (0.3) [nm]</b></dt>
 <dd>the soft-core sigma for particles which have a C6 or C12 parameter equal
 to zero or a sigma smaller than <b>sc-sigma</b></dd>
@@ -1658,24 +1666,24 @@ simulation specified in the first group of <b>ref_t</b> is used.</dd>
 <dt><b>symmetrized-transition-matrix: (no) </b></dt>
 <dd>Whether to symmetrize the empirical transition matrix. In the infinite limit the matrix will be symmetric, but will diverge with statistical noise for short timescales.  Forced symmetrization, by using the matrix T_sym = 1/2 (T + transpose(T)), removes problems like the existence of (small magnitude) negative eigenvalues.</dd>
 <dt><b>mininum-var-min: (100)</b></dt>
-<dd> The <b>min-variance</b> strategy (option of <b>lmc-stats</b> is only valid for larger number of samples, and can get stuck if too few samples are used at each state.  <b>mininum-var-min</b> is the minimum number of samples that each state that are allowed before the <b>min-variance</b> strategy is activated if selected.
+<dd> The <b>min-variance</b> strategy (option of <b>lmc-stats</b> is only valid for larger number of samples, and can get stuck if too few samples are used at each state.  <b>mininum-var-min</b> is the minimum number of samples that each state that are allowed before the <b>min-variance</b> strategy is activated if selected.</dd>
 <dt><b>init-lambda-weights: </b></dt>
-<dd>The initial weights (free energies) used for the expanded ensemble states.  Default is a vector of zero weights. format is similar to the lambda vector settings in <b>fep-lambdas</b>, except the weights can be any floating point number.  Units are kT. Its length must match the lambda vector lengths.<dd>
-<dt><b>lmc-weights-equil: (no)</b><dt>
+<dd>The initial weights (free energies) used for the expanded ensemble states.  Default is a vector of zero weights. format is similar to the lambda vector settings in <b>fep-lambdas</b>, except the weights can be any floating point number.  Units are kT. Its length must match the lambda vector lengths.</dd>
+<dt><b>lmc-weights-equil: (no)</b></dt>
 <dd><dl compact>
-<dt><b>no</b><dt>
+<dt><b>no</b></dt>
 <dd>Expanded ensemble weights continue to be updated throughout the simulation.</dd>
-<dt><b>yes</b><dt>
+<dt><b>yes</b></dt>
 <dd>The input expanded ensemble weights are treated as equilibrated, and are not updated throughout the simulation.</dd>
-<dt><b>wl-delta</b><dt>
+<dt><b>wl-delta</b></dt>
 <dd>Expanded ensemble weight updating is stopped when the Wang-Landau incrementor falls below the value specified by <b>weight-equil-wl-delta</b>.</dd>
-<dt><b>number-all-lambda</b><dt>
+<dt><b>number-all-lambda</b></dt>
 <dd>Expanded ensemble weight updating is stopped when the number of samples at all of the lambda states is greater than the value specified by <b>weight-equil-number-all-lambda</b>.</dd>
-<dt><b>number-steps</b><dt>
+<dt><b>number-steps</b></dt>
 <dd>Expanded ensemble weight updating is stopped when the number of steps is greater than the level specified by <b>weight-equil-number-steps</b>.</dd>
-<dt><b>number-samples</b><dt>
+<dt><b>number-samples</b></dt>
 <dd>Expanded ensemble weight updating is stopped when the number of total samples across all lambda states is greater than the level specified by <b>weight-equil-number-samples</b>.</dd>
-<dt><b>count-ratio</b><dt>
+<dt><b>count-ratio</b></dt>
 <dd>Expanded ensemble weight updating is stopped when the ratio of samples at the least sampled lambda state and most sampled lambda state greater than the value specified by <b>weight-equil-count-ratio</b>.</dd> 
 </dl>
 <dt><b>simulated-tempering: (no)</b></dt>
@@ -1687,11 +1695,11 @@ simulation specified in the first group of <b>ref_t</b> is used.</dd>
 <dt><b>simulated-tempering-scaling: (linear)</b></dt>
 <dd>Controls the way that the temperatures at intermediate lambdas are calculated from the <b>temperature-lambda</b> part of the lambda vector.</dd>
 <dd><dl compact>
-<dt><b>linear</b><dt>
+<dt><b>linear</b></dt>
 <dd>Linearly interpolates the temperatures using the values of <b>temperature-lambda</b>,i.e. if <b>sim-temp-low</b>=300, <b>sim-temp-high</b>=400, then lambda=0.5 correspond to a temperature of 350. A nonlinear set of temperatures can always be implemented with uneven spacing in lambda.</dd>
-<dt><b>geometric</b><dt>
-<dd> Interpolates temperatures geometrically between <b>sim-temp-low</b> and <b>sim-temp-high</b>. The ith state has temperature <b>sim-temp-low</b> * (<b>sim-temp-high</b>/<b>sim-temp-low</b>)^(i/(ntemps-1)).  Should give roughly equal exchange for constant heat capacity, though of course things simulations that involve protein folding have very high heat capacity peaks.</dd>
-<dt><b>exponential</b><dt>
+<dt><b>geometric</b></dt>
+<dd> Interpolates temperatures geometrically between <b>sim-temp-low</b> and <b>sim-temp-high</b>. The i-th state has temperature <b>sim-temp-low</b> * (<b>sim-temp-high</b>/<b>sim-temp-low</b>) to the power (i/(ntemps-1)).  Should give roughly equal exchange for constant heat capacity, though of course things simulations that involve protein folding have very high heat capacity peaks.</dd>
+<dt><b>exponential</b></dt>
 <dd> Interpolates temperatures exponentially between <b>sim-temp-low</b> and <b>sim-temp-high</b>. The ith state has temperature
 <b>sim-temp-low</b> + (<b>sim-temp-high</b>-<b>sim-temp-low</b>)*((exp(<b>temperature-lambdas</b>[i])-1)/(exp(1.0)-1)).</dd>
 </dl>
index 2a5577e8a2d3c60a9fc945af9b33f86577585175..2c003ba0245230b628ef7f216721b50d88d83f15 100644 (file)
 #include "swindirect.h"
 #endif
 
+/* default name mangling maybe wrong on exotic plattforms */
+#define F77_FUNC(name,NAME) name ## _
+
 /* Define if we have pipes */
 #cmakedefine HAVE_PIPES
 
diff --git a/src/contrib/BuildMdrunOpenMM.cmake b/src/contrib/BuildMdrunOpenMM.cmake
new file mode 100644 (file)
index 0000000..52aaec6
--- /dev/null
@@ -0,0 +1,63 @@
+#
+# This file is part of the GROMACS molecular simulation package.
+#
+# Copyright (c) 2012, by the GROMACS development team, led by
+# David van der Spoel, Berk Hess, 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.
+#
+
+include_directories(${OpenMM_INCLUDE_DIR})
+link_directories(${OpenMM_LIBRARY_DIR}) 
+# with this define no evn.var. is needed with OPENMM_PLUGIN_DIR
+# if the same OpenMM installation is used for running and building 
+add_definitions( -DOPENMM_PLUGIN_DIR="${OpenMM_PLUGIN_DIR}" ) 
+file(TO_CMAKE_PATH ${OpenMM_PLUGIN_DIR} _path)
+add_library(openmm_api_wrapper STATIC openmm_wrapper.cpp)
+target_link_libraries(openmm_api_wrapper ${OpenMM_LIBRARIES})
+list(APPEND GMX_EXTRA_LIBRARIES openmm_api_wrapper ${OpenMM_LIBRARIES})   
+
+list(REMOVE_ITEM MDRUN_SOURCES mdrun.c)
+list(APPEND MDRUN_SOURCES
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/contrib/md_openmm.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/contrib/mdrun_openmm.c)
+
+# this is to circumvent the following MSVC error: 
+# warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs
+# fatal error LNK1169: one or more multiply defined symbols found
+if(GMX_OPENMM AND MSVC)
+    set_target_properties(mdrun PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMT")
+endif()
+
+include_directories(${CMAKE_SOURCE_DIR}/src/gmxlib/gpu_utils)
+
+set_source_files_properties(main.c PROPERTIES LANGUAGE CXX)
+if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+    set_source_files_properties(main.c PROPERTIES COMPILE_FLAGS "-x c++")
+endif()
index b43b007dff191b8f90c63f07bcd0ed82730aa89f..4ed8a48a09f64fe5a8b979d6a1ff59b3ac22b2bc 100644 (file)
@@ -1,7 +1,84 @@
 set(CONTRIB_PROGRAMS 
      #add here any programs you want to compile
+
 )
 
+# Uncomment the next line to build OpenMM:
+#option(GMX_OPENMM "Accelerated execution on GPUs through the OpenMM library (no longer supported" ON)
+
+# At run time, you may need to set the environment variable
+# OPENMM_PLUGIN_DIR=PATH_TO_GROMACS/openmm/lib/plugins
+# to make things work
+
+if(GMX_OPENMM)
+    if(GMX_GPU)
+        message(FATAL_ERROR "The OpenMM build is not compatible with the native GPU build")
+    endif()
+
+    enable_language(CXX)
+    set (GMX_BINARY_SUFFIX "-openmm")
+    set (GMX_LIBS_SUFFIX "_openmm")
+
+#######################################################################
+# Check for options incompatible with OpenMM build                    #
+#######################################################################
+    # we'll use the built-in fft to avoid unnecessary dependencies
+    string(TOUPPER ${GMX_FFT_LIBRARY} GMX_FFT_LIBRARY)
+    if(NOT ${GMX_FFT_LIBRARY} STREQUAL "FFTPACK")
+        message(STATUS "No external FFT libraries needed for the OpenMM build, switching to fftpack!")
+        set(GMX_FFT_LIBRARY "fftpack" CACHE STRING 
+               "No external FFT libraries needed for the OpenMM build, switching to  fftpack!" FORCE)
+    endif()
+    if(GMX_MPI)
+        message(FATAL_ERROR "The OpenMM build is not compatible with MPI!")
+    endif(GMX_MPI)
+    if(GMX_THREAD_MPI)
+        message(STATUS "Thread-MPI not compatible with OpenMM, disabled!")
+        set(GMX_THREAD_MPI OFF CACHE BOOL
+               "Thread-MPI not compatible with OpenMM build, disabled!" FORCE)
+    endif(GMX_THREAD_MPI)
+    if(GMX_OPENMP)
+        message(STATUS "OpenMP multithreading not compatible with OpenMM, disabled")
+        set(GMX_OPENMP OFF CACHE BOOL
+            "OpenMP multithreading not compatible with OpenMM, disabled!" FORCE)
+    endif()
+    if(GMX_SOFTWARE_INVSQRT)
+        set(GMX_SOFTWARE_INVSQRT OFF CACHE STRING 
+                "The OpenMM build does not need GROMACS software 1/sqrt!" FORCE)
+    endif(GMX_SOFTWARE_INVSQRT)
+    string(TOUPPER ${GMX_CPU_ACCELERATION} GMX_CPU_ACCELERATION)
+    if(NOT GMX_CPU_ACCELERATION STREQUAL "NONE")
+        message(STATUS "Switching off CPU-based acceleration, the OpenMM build does not support/need any!")
+        set(GMX_CPU_ACCELERATION "None" CACHE STRING
+            "Switching off CPU-based acceleration, the OpenMM build does not support/need any!" FORCE)
+    endif()
+    if(GMX_FAHCORE)
+        message(FATAL_ERROR "The OpenMM build does not support FAH build!")
+    endif(GMX_FAHCORE)
+    if(GMX_DOUBLE)
+        message(FATAL_ERROR  "The OpenMM-build does not support double precision calculations!")
+    endif()
+
+    set(CUDA_BUILD_EMULATION OFF)
+    find_package(CUDA 3.1 REQUIRED)
+    add_definitions(-DGMX_OPENMM)
+    if(CMAKE_BUILD_TYPE STREQUAL "DEBUG")    
+        set(CUDA_VERBOSE_BUILD ON)
+    endif()
+    list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/src/contrib)
+    find_package(OpenMM) 
+
+    # mark as advanced the unused variables
+    mark_as_advanced(FORCE GMX_CPU_ACCELERATION GMX_MPI GMX_FFT_LIBRARY 
+        GMX_QMMM_PROGRAM GMX_THREAD_MPI GMX_DOUBLE)
+
+else(GMX_OPENMM)
+
+     mark_as_advanced(CLEAR GMX_CPU_ACCELERATION GMX_MPI GMX_FFT_LIBRARY 
+        GMX_QMMM_PROGRAM GMX_THREAD_MPI GMX_DOUBLE)
+
+endif(GMX_OPENMM)
+
 foreach(PROG ${CONTRIB_PROGRAMS})
         add_executable(${PROG} ${PROG}.c ${NGMX_COMMON_SOURCE})
        set_target_properties(${PROG} PROPERTIES OUTPUT_NAME "${PROG}${GMX_BINARY_SUFFIX}")
similarity index 91%
rename from src/programs/mdrun/md_openmm.c
rename to src/contrib/md_openmm.c
index a12bdda02c52ad39d29c0ab6e144c43145fc41ff..d5a15e73c58e49830c0f7ccc37d1448d1b726654 100644 (file)
@@ -1,36 +1,39 @@
-/* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
+/*
+ * This file is part of the GROMACS molecular simulation package.
  *
- * 
- *                This source code is part of
- * 
- *                 G   R   O   M   A   C   S
- * 
- *          GROningen MAchine for Chemical Simulations
- * 
- * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2010, The GROMACS development team,
  * check out http://www.gromacs.org for more information.
-
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
+ * Copyright (c) 2012, by the GROMACS development team, led by
+ * David van der Spoel, Berk Hess, 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.
- * 
- * If you want to redistribute modifications, 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 www.gromacs.org.
- * 
+ *
+ * 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 papers on the package - you can find them in the top README file.
- * 
- * For more info, check our website at http://www.gromacs.org
- * 
- * And Hey:
- * Gallium Rubidium Oxygen Manganese Argon Carbon Silicon
+ * the research papers on the package. Check out http://www.gromacs.org.
  */
 
 #ifdef HAVE_CONFIG_H
@@ -70,6 +73,7 @@
 #include "pme.h"
 #include "mdatoms.h"
 #include "qmmm.h"
+#include "mpelogging.h"
 #include "domdec.h"
 #include "partdec.h"
 #include "topsort.h"
@@ -356,6 +360,8 @@ double do_md_openmm(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
     {
         wallcycle_start(wcycle,ewcSTEP);
 
+        GMX_MPE_LOG(ev_timestep1);
+
         bLastStep = (step_rel == ir->nsteps);
         t = t0 + step*ir->delta_t;
 
@@ -374,6 +380,7 @@ double do_md_openmm(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
         }
 
         clear_mat(force_vir);
+        GMX_MPE_LOG(ev_timestep2);
 
         /* We write a checkpoint at this MD step when:
          * either when we signalled through gs (in OpenMM NS works different),
@@ -393,6 +400,8 @@ double do_md_openmm(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
          * the update.
          * for RerunMD t is read from input trajectory
          */
+        GMX_MPE_LOG(ev_output_start);
+
         mdof_flags = 0;
         if (do_per_step(step,ir->nstxout))
         {
@@ -461,6 +470,8 @@ double do_md_openmm(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
             }
             wallcycle_stop(wcycle,ewcTRAJ);
         }
+        GMX_MPE_LOG(ev_output_finish);
+
 
         /* Determine the wallclock run time up till now */
         run_time = gmx_gettime() - (double)runtime->real;
diff --git a/src/contrib/md_openmm.h b/src/contrib/md_openmm.h
new file mode 100644 (file)
index 0000000..d177db7
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2010, The GROMACS development team,
+ * check out http://www.gromacs.org for more information.
+ * Copyright (c) 2012, by the GROMACS development team, led by
+ * David van der Spoel, Berk Hess, 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.
+ */
+#ifndef _MD_OPENMM_H
+#define _MD_OPENMM_H
+
+double do_md_openmm(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
+             const output_env_t oenv, gmx_bool bVerbose,gmx_bool bCompact,
+             int nstglobalcomm,
+             gmx_vsite_t *vsite,gmx_constr_t constr,
+             int stepout,t_inputrec *ir,
+             gmx_mtop_t *top_global,
+             t_fcdata *fcd,
+             t_state *state_global,
+             t_mdatoms *mdatoms,
+             t_nrnb *nrnb,gmx_wallcycle_t wcycle,
+             gmx_edsam_t ed,t_forcerec *fr,
+             int repl_ex_nst, int repl_ex_nex, int repl_ex_seed,
+             gmx_membed_t membed,
+             real cpt_period,real max_hours,
+             const char *deviceOptions,
+             unsigned long Flags,
+             gmx_runtime_t *runtime);
+
+#endif /* _MD_OPENMM_H */
diff --git a/src/contrib/mdrun_openmm.c b/src/contrib/mdrun_openmm.c
new file mode 100644 (file)
index 0000000..53bba75
--- /dev/null
@@ -0,0 +1,509 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2004, The GROMACS development team,
+ * check out http://www.gromacs.org for more information.
+ * Copyright (c) 2012, by the GROMACS development team, led by
+ * David van der Spoel, Berk Hess, 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.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "typedefs.h"
+#include "macros.h"
+#include "copyrite.h"
+#include "main.h"
+#include "statutil.h"
+#include "smalloc.h"
+#include "futil.h"
+#include "smalloc.h"
+#include "edsam.h"
+#include "mdrun.h"
+#include "xmdrun.h"
+#include "checkpoint.h"
+#ifdef GMX_THREAD_MPI
+#include "thread_mpi.h"
+#endif
+
+/* afm stuf */
+#include "pull.h"
+
+int cmain(int argc,char *argv[])
+{
+  const char *desc[] = {
+    "This is an experimental release of GROMACS for accelerated",
+       "Molecular Dynamics simulations on GPU processors. Support is provided",
+       "by the OpenMM library (https://simtk.org/home/openmm).[PAR]",
+       "*Warning*[BR]",
+       "This release is targeted at developers and advanced users and",
+       "care should be taken before production use. The following should be",
+       "noted before using the program:[PAR]",
+       " * The current release runs only on modern nVidia GPU hardware with CUDA support.",
+       "Make sure that the necessary CUDA drivers and libraries for your operating system",
+       "are already installed. The CUDA SDK also should be installed in order to compile",
+       "the program from source (http://www.nvidia.com/object/cuda_home.html).[PAR]",
+       " * Multiple GPU cards are not supported.[PAR]",
+       " * Only a small subset of the GROMACS features and options are supported on the GPUs.",
+       "See below for a detailed list.[PAR]",
+       " * Consumer level GPU cards are known to often have problems with faulty memory.",
+       "It is recommended that a full memory check of the cards is done at least once",
+       "(for example, using the memtest=full option).",
+       "A partial memory check (for example, memtest=15) before and",
+       "after the simulation run would help spot",
+       "problems resulting from processor overheating.[PAR]",
+       " * The maximum size of the simulated systems depends on the available",
+       "GPU memory,for example, a GTX280 with 1GB memory has been tested with systems",
+       "of up to about 100,000 atoms.[PAR]",
+       " * In order to take a full advantage of the GPU platform features, many algorithms",
+       "have been implemented in a very different way than they are on the CPUs.",
+       "Therefore numercal correspondence between properties of the state of",
+       "simulated systems should not be expected. Moreover, the values will likely vary",
+       "when simulations are done on different GPU hardware.[PAR]",
+       " * Frequent retrieval of system state information such as",
+       "trajectory coordinates and energies can greatly influence the performance",
+       "of the program due to slow CPU<->GPU memory transfer speed.[PAR]",
+       " * MD algorithms are complex, and although the Gromacs code is highly tuned for them,",
+       "they often do not translate very well onto the streaming architetures.",
+       "Realistic expectations about the achievable speed-up from test with GTX280:",
+       "For small protein systems in implicit solvent using all-vs-all kernels the acceleration",
+       "can be as high as 20 times, but in most other setups involving cutoffs and PME the",
+       "acceleration is usually only ~4 times relative to a 3GHz CPU.[PAR]",
+       "Supported features:[PAR]",
+       " * Integrators: md/md-vv/md-vv-avek, sd/sd1 and bd.\n",
+       " * Long-range interactions (option coulombtype): Reaction-Field, Ewald, PME, and cut-off (for Implicit Solvent only)\n",
+       " * Temperature control: Supported only with the md/md-vv/md-vv-avek, sd/sd1 and bd integrators.\n",
+       " * Pressure control: Supported.\n",
+       " * Implicit solvent: Supported.\n",
+       "A detailed description can be found on the GROMACS website:\n",
+       "http://www.gromacs.org/gpu[PAR]",
+/* From the original mdrun documentaion */
+    "The [TT]mdrun[tt] program reads the run input file ([TT]-s[tt])",
+    "and distributes the topology over nodes if needed.",
+    "[TT]mdrun[tt] produces at least four output files.",
+    "A single log file ([TT]-g[tt]) is written, unless the option",
+    "[TT]-seppot[tt] is used, in which case each node writes a log file.",
+    "The trajectory file ([TT]-o[tt]), contains coordinates, velocities and",
+    "optionally forces.",
+    "The structure file ([TT]-c[tt]) contains the coordinates and",
+    "velocities of the last step.",
+    "The energy file ([TT]-e[tt]) contains energies, the temperature,",
+    "pressure, etc, a lot of these things are also printed in the log file.",
+    "Optionally coordinates can be written to a compressed trajectory file",
+    "([TT]-x[tt]).[PAR]",
+/* openmm specific information */
+       "Usage with OpenMM:[BR]",
+       "[TT]mdrun -device \"OpenMM:platform=Cuda,memtest=15,deviceid=0,force-device=no\"[tt][PAR]",
+       "Options:[PAR]",
+       "      [TT]platform[tt] = Cuda\t\t:\tThe only available value. OpenCL support will be available in future.\n",
+       "      [TT]memtest[tt] = 15\t\t:\tRun a partial, random GPU memory test for the given amount of seconds. A full test",
+       "(recommended!) can be run with \"memtest=full\". Memory testing can be disabled with \"memtest=off\".\n",
+       "      [TT]deviceid[tt] = 0\t\t:\tSpecify the target device when multiple cards are present.",
+       "Only one card can be used at any given time though.\n",
+       "      [TT]force-device[tt] = no\t\t:\tIf set to \"yes\" [TT]mdrun[tt]  will be forced to execute on",
+       "hardware that is not officially supported. GPU acceleration can also be achieved on older",
+       "but Cuda capable cards, although the simulation might be too slow, and the memory limits too strict.",
+  };
+  t_commrec    *cr;
+  t_filenm fnm[] = {
+    { efTPX, NULL,      NULL,       ffREAD },
+    { efTRN, "-o",      NULL,       ffWRITE },
+    { efXTC, "-x",      NULL,       ffOPTWR },
+    { efCPT, "-cpi",    NULL,       ffOPTRD },
+    { efCPT, "-cpo",    NULL,       ffOPTWR },
+    { efSTO, "-c",      "confout",  ffWRITE },
+    { efEDR, "-e",      "ener",     ffWRITE },
+    { efLOG, "-g",      "md",       ffWRITE },
+    { efXVG, "-dhdl",   "dhdl",     ffOPTWR },
+    { efXVG, "-field",  "field",    ffOPTWR },
+    { efXVG, "-table",  "table",    ffOPTRD },
+    { efXVG, "-tabletf", "tabletf",    ffOPTRD },
+    { efXVG, "-tablep", "tablep",   ffOPTRD },
+    { efXVG, "-tableb", "table",    ffOPTRD },
+    { efTRX, "-rerun",  "rerun",    ffOPTRD },
+    { efXVG, "-tpi",    "tpi",      ffOPTWR },
+    { efXVG, "-tpid",   "tpidist",  ffOPTWR },
+    { efEDI, "-ei",     "sam",      ffOPTRD },
+    { efEDO, "-eo",     "sam",      ffOPTWR },
+    { efGCT, "-j",      "wham",     ffOPTRD },
+    { efGCT, "-jo",     "bam",      ffOPTWR },
+    { efXVG, "-ffout",  "gct",      ffOPTWR },
+    { efXVG, "-devout", "deviatie", ffOPTWR },
+    { efXVG, "-runav",  "runaver",  ffOPTWR },
+    { efXVG, "-px",     "pullx",    ffOPTWR },
+    { efXVG, "-pf",     "pullf",    ffOPTWR },
+    { efXVG, "-ro",     "rotation", ffOPTWR },
+    { efLOG, "-ra",     "rotangles",ffOPTWR },
+    { efLOG, "-rs",     "rotslabs", ffOPTWR },
+    { efLOG, "-rt",     "rottorque",ffOPTWR },
+    { efMTX, "-mtx",    "nm",       ffOPTWR },
+    { efNDX, "-dn",     "dipole",   ffOPTWR },
+    { efRND, "-multidir",NULL,      ffOPTRDMULT},
+    { efDAT, "-membed", "membed",   ffOPTRD },
+    { efTOP, "-mp",     "membed",   ffOPTRD },
+    { efNDX, "-mn",     "membed",   ffOPTRD }
+  };
+#define NFILE asize(fnm)
+
+  /* Command line options ! */
+  gmx_bool bCart        = FALSE;
+  gmx_bool bPPPME       = FALSE;
+  gmx_bool bPartDec     = FALSE;
+  gmx_bool bDDBondCheck = TRUE;
+  gmx_bool bDDBondComm  = TRUE;
+  gmx_bool bTunePME     = TRUE;
+  gmx_bool bTestVerlet  = FALSE;
+  gmx_bool bVerbose     = FALSE;
+  gmx_bool bCompact     = TRUE;
+  gmx_bool bSepPot      = FALSE;
+  gmx_bool bRerunVSite  = FALSE;
+  gmx_bool bIonize      = FALSE;
+  gmx_bool bConfout     = TRUE;
+  gmx_bool bReproducible = FALSE;
+    
+  int  npme=-1;
+  int  nmultisim=0;
+  int  nstglobalcomm=-1;
+  int  repl_ex_nst=0;
+  int  repl_ex_seed=-1;
+  int  repl_ex_nex=0;
+  int  nstepout=100;
+  int  resetstep=-1;
+  int  nsteps=-2; /* the value -2 means that the mdp option will be used */
+  
+  rvec realddxyz={0,0,0};
+  const char *ddno_opt[ddnoNR+1] =
+    { NULL, "interleave", "pp_pme", "cartesian", NULL };
+  const char *dddlb_opt[] =
+    { NULL, "auto", "no", "yes", NULL };
+  const char *nbpu_opt[] =
+    { NULL, "auto", "cpu", "gpu", "gpu_cpu", NULL };
+  real rdd=0.0,rconstr=0.0,dlb_scale=0.8,pforce=-1;
+  char *ddcsx=NULL,*ddcsy=NULL,*ddcsz=NULL;
+  real cpt_period=15.0,max_hours=-1;
+  gmx_bool bAppendFiles=TRUE;
+  gmx_bool bKeepAndNumCPT=FALSE;
+  gmx_bool bResetCountersHalfWay=FALSE;
+  output_env_t oenv=NULL;
+  const char *deviceOptions = "";
+
+  gmx_hw_opt_t hw_opt={0,0,0,0,TRUE,FALSE,0,NULL};
+
+  t_pargs pa[] = {
+
+    { "-pd",      FALSE, etBOOL,{&bPartDec},
+      "Use particle decompostion" },
+    { "-dd",      FALSE, etRVEC,{&realddxyz},
+      "Domain decomposition grid, 0 is optimize" },
+    { "-ddorder", FALSE, etENUM, {ddno_opt},
+      "DD node order" },
+    { "-npme",    FALSE, etINT, {&npme},
+      "Number of separate nodes to be used for PME, -1 is guess" },
+    { "-nt",      FALSE, etINT, {&hw_opt.nthreads_tot},
+      "Total number of threads to start (0 is guess)" },
+    { "-ntmpi",   FALSE, etINT, {&hw_opt.nthreads_tmpi},
+      "Number of thread-MPI threads to start (0 is guess)" },
+    { "-ntomp",   FALSE, etINT, {&hw_opt.nthreads_omp},
+      "Number of OpenMP threads per MPI process/thread to start (0 is guess)" },
+    { "-ntomp_pme", FALSE, etINT, {&hw_opt.nthreads_omp_pme},
+      "Number of OpenMP threads per MPI process/thread to start (0 is -ntomp)" },
+    { "-pin",     FALSE, etBOOL, {&hw_opt.bThreadPinning},
+      "Pin OpenMP threads to cores" },
+    { "-pinht",   FALSE, etBOOL, {&hw_opt.bPinHyperthreading},
+      "Always pin threads to Hyper-Threading cores" },
+    { "-pinoffset", FALSE, etINT, {&hw_opt.core_pinning_offset},
+      "Core offset for pinning (for running multiple mdrun processes on a single physical node)" },
+    { "-gpu_id",  FALSE, etSTR, {&hw_opt.gpu_id},
+      "List of GPU id's to use" },
+    { "-ddcheck", FALSE, etBOOL, {&bDDBondCheck},
+      "Check for all bonded interactions with DD" },
+    { "-ddbondcomm", FALSE, etBOOL, {&bDDBondComm},
+      "HIDDENUse special bonded atom communication when [TT]-rdd[tt] > cut-off" },
+    { "-rdd",     FALSE, etREAL, {&rdd},
+      "The maximum distance for bonded interactions with DD (nm), 0 is determine from initial coordinates" },
+    { "-rcon",    FALSE, etREAL, {&rconstr},
+      "Maximum distance for P-LINCS (nm), 0 is estimate" },
+    { "-dlb",     FALSE, etENUM, {dddlb_opt},
+      "Dynamic load balancing (with DD)" },
+    { "-dds",     FALSE, etREAL, {&dlb_scale},
+      "Minimum allowed dlb scaling of the DD cell size" },
+    { "-ddcsx",   FALSE, etSTR, {&ddcsx},
+      "HIDDENThe DD cell sizes in x" },
+    { "-ddcsy",   FALSE, etSTR, {&ddcsy},
+      "HIDDENThe DD cell sizes in y" },
+    { "-ddcsz",   FALSE, etSTR, {&ddcsz},
+      "HIDDENThe DD cell sizes in z" },
+    { "-gcom",    FALSE, etINT,{&nstglobalcomm},
+      "Global communication frequency" },
+    { "-nb",      FALSE, etENUM, {&nbpu_opt},
+      "Calculate non-bonded interactions on" },
+    { "-tunepme", FALSE, etBOOL, {&bTunePME},  
+      "Optimize PME load between PP/PME nodes or GPU/CPU" },
+    { "-testverlet", FALSE, etBOOL, {&bTestVerlet},
+      "Test the Verlet non-bonded scheme" },
+    { "-v",       FALSE, etBOOL,{&bVerbose},  
+      "Be loud and noisy" },
+    { "-compact", FALSE, etBOOL,{&bCompact},  
+      "Write a compact log file" },
+    { "-seppot",  FALSE, etBOOL, {&bSepPot},
+      "Write separate V and dVdl terms for each interaction type and node to the log file(s)" },
+    { "-pforce",  FALSE, etREAL, {&pforce},
+      "Print all forces larger than this (kJ/mol nm)" },
+    { "-reprod",  FALSE, etBOOL,{&bReproducible},  
+      "Try to avoid optimizations that affect binary reproducibility" },
+    { "-cpt",     FALSE, etREAL, {&cpt_period},
+      "Checkpoint interval (minutes)" },
+    { "-cpnum",   FALSE, etBOOL, {&bKeepAndNumCPT},
+      "Keep and number checkpoint files" },
+    { "-append",  FALSE, etBOOL, {&bAppendFiles},
+      "Append to previous output files when continuing from checkpoint instead of adding the simulation part number to all file names" },
+    { "-nsteps",  FALSE, etINT, {&nsteps},
+      "Run this number of steps, overrides .mdp file option" },
+    { "-maxh",   FALSE, etREAL, {&max_hours},
+      "Terminate after 0.99 times this time (hours)" },
+    { "-multi",   FALSE, etINT,{&nmultisim}, 
+      "Do multiple simulations in parallel" },
+    { "-replex",  FALSE, etINT, {&repl_ex_nst}, 
+      "Attempt replica exchange periodically with this period (steps)" },
+    { "-nex",  FALSE, etINT, {&repl_ex_nex},
+      "Number of random exchanges to carry out each exchange interval (N^3 is one suggestion).  -nex zero or not specified gives neighbor replica exchange." },
+    { "-reseed",  FALSE, etINT, {&repl_ex_seed}, 
+      "Seed for replica exchange, -1 is generate a seed" },
+    { "-rerunvsite", FALSE, etBOOL, {&bRerunVSite},
+      "HIDDENRecalculate virtual site coordinates with [TT]-rerun[tt]" },
+    { "-ionize",  FALSE, etBOOL,{&bIonize},
+      "Do a simulation including the effect of an X-Ray bombardment on your system" },
+    { "-confout", FALSE, etBOOL, {&bConfout},
+      "HIDDENWrite the last configuration with [TT]-c[tt] and force checkpointing at the last step" },
+    { "-stepout", FALSE, etINT, {&nstepout},
+      "HIDDENFrequency of writing the remaining runtime" },
+    { "-resetstep", FALSE, etINT, {&resetstep},
+      "HIDDENReset cycle counters after these many time steps" },
+    { "-resethway", FALSE, etBOOL, {&bResetCountersHalfWay},
+      "HIDDENReset the cycle counters after half the number of steps or halfway [TT]-maxh[tt]" },
+    { "-device",  FALSE, etSTR, {&deviceOptions},
+      "Device option string" }
+  };
+  gmx_edsam_t  ed;
+  unsigned long Flags, PCA_Flags;
+  ivec     ddxyz;
+  int      dd_node_order;
+  gmx_bool     bAddPart;
+  FILE     *fplog,*fptest;
+  int      sim_part,sim_part_fn;
+  const char *part_suffix=".part";
+  char     suffix[STRLEN];
+  int      rc;
+  char **multidir=NULL;
+
+
+  cr = init_par(&argc,&argv);
+
+  if (MASTER(cr))
+    CopyRight(stderr, argv[0]);
+
+  PCA_Flags = (PCA_CAN_SET_DEFFNM | (MASTER(cr) ? 0 : PCA_QUIET));
+  
+  /* Comment this in to do fexist calls only on master
+   * works not with rerun or tables at the moment
+   * also comment out the version of init_forcerec in md.c 
+   * with NULL instead of opt2fn
+   */
+  /*
+     if (!MASTER(cr))
+     {
+     PCA_Flags |= PCA_NOT_READ_NODE;
+     }
+     */
+
+  parse_common_args(&argc,argv,PCA_Flags, NFILE,fnm,asize(pa),pa,
+                    asize(desc),desc,0,NULL, &oenv);
+
+
+
+  /* we set these early because they might be used in init_multisystem() 
+     Note that there is the potential for npme>nnodes until the number of
+     threads is set later on, if there's thread parallelization. That shouldn't
+     lead to problems. */ 
+  dd_node_order = nenum(ddno_opt);
+  cr->npmenodes = npme;
+
+  /* now check the -multi and -multidir option */
+  if (opt2bSet("-multidir", NFILE, fnm))
+  {
+      int i;
+      if (nmultisim > 0)
+      {
+          gmx_fatal(FARGS, "mdrun -multi and -multidir options are mutually exclusive.");
+      }
+      nmultisim = opt2fns(&multidir, "-multidir", NFILE, fnm);
+  }
+
+
+  if (repl_ex_nst != 0 && nmultisim < 2)
+      gmx_fatal(FARGS,"Need at least two replicas for replica exchange (option -multi)");
+
+  if (repl_ex_nex < 0)
+      gmx_fatal(FARGS,"Replica exchange number of exchanges needs to be positive");
+
+  if (nmultisim > 1) {
+#ifndef GMX_THREAD_MPI
+    gmx_bool bParFn = (multidir == NULL);
+    init_multisystem(cr, nmultisim, multidir, NFILE, fnm, bParFn);
+#else
+    gmx_fatal(FARGS,"mdrun -multi is not supported with the thread library.Please compile GROMACS with MPI support");
+#endif
+  }
+
+  bAddPart = !bAppendFiles;
+
+  /* Check if there is ANY checkpoint file available */        
+  sim_part    = 1;
+  sim_part_fn = sim_part;
+  if (opt2bSet("-cpi",NFILE,fnm))
+  {
+      if (bSepPot && bAppendFiles)
+      {
+          gmx_fatal(FARGS,"Output file appending is not supported with -seppot");
+      }
+
+      bAppendFiles =
+                read_checkpoint_simulation_part(opt2fn_master("-cpi", NFILE,
+                                                              fnm,cr),
+                                                &sim_part_fn,NULL,cr,
+                                                bAppendFiles,NFILE,fnm,
+                                                part_suffix,&bAddPart);
+      if (sim_part_fn==0 && MASTER(cr))
+      {
+          fprintf(stdout,"No previous checkpoint file present, assuming this is a new run.\n");
+      }
+      else
+      {
+          sim_part = sim_part_fn + 1;
+      }
+
+      if (MULTISIM(cr) && MASTER(cr))
+      {
+          check_multi_int(stdout,cr->ms,sim_part,"simulation part");
+      }
+  } 
+  else
+  {
+      bAppendFiles = FALSE;
+  }
+
+  if (!bAppendFiles)
+  {
+      sim_part_fn = sim_part;
+  }
+
+  if (bAddPart)
+  {
+      /* Rename all output files (except checkpoint files) */
+      /* create new part name first (zero-filled) */
+      sprintf(suffix,"%s%04d",part_suffix,sim_part_fn);
+
+      add_suffix_to_output_names(fnm,NFILE,suffix);
+      if (MASTER(cr))
+      {
+          fprintf(stdout,"Checkpoint file is from part %d, new output files will be suffixed '%s'.\n",sim_part-1,suffix);
+      }
+  }
+
+  Flags = opt2bSet("-rerun",NFILE,fnm) ? MD_RERUN : 0;
+  Flags = Flags | (bSepPot       ? MD_SEPPOT       : 0);
+  Flags = Flags | (bIonize       ? MD_IONIZE       : 0);
+  Flags = Flags | (bPartDec      ? MD_PARTDEC      : 0);
+  Flags = Flags | (bDDBondCheck  ? MD_DDBONDCHECK  : 0);
+  Flags = Flags | (bDDBondComm   ? MD_DDBONDCOMM   : 0);
+  Flags = Flags | (bTunePME      ? MD_TUNEPME      : 0);
+  Flags = Flags | (bTestVerlet   ? MD_TESTVERLET   : 0);
+  Flags = Flags | (bConfout      ? MD_CONFOUT      : 0);
+  Flags = Flags | (bRerunVSite   ? MD_RERUN_VSITE  : 0);
+  Flags = Flags | (bReproducible ? MD_REPRODUCIBLE : 0);
+  Flags = Flags | (bAppendFiles  ? MD_APPENDFILES  : 0); 
+  Flags = Flags | (opt2parg_bSet("-append", asize(pa),pa) ? MD_APPENDFILESSET : 0); 
+  Flags = Flags | (bKeepAndNumCPT ? MD_KEEPANDNUMCPT : 0); 
+  Flags = Flags | (sim_part>1    ? MD_STARTFROMCPT : 0); 
+  Flags = Flags | (bResetCountersHalfWay ? MD_RESETCOUNTERSHALFWAY : 0);
+
+
+  /* We postpone opening the log file if we are appending, so we can 
+     first truncate the old log file and append to the correct position 
+     there instead.  */
+  if ((MASTER(cr) || bSepPot) && !bAppendFiles) 
+  {
+      gmx_log_open(ftp2fn(efLOG,NFILE,fnm),cr,
+                   !bSepPot,Flags & MD_APPENDFILES,&fplog);
+      CopyRight(fplog,argv[0]);
+      please_cite(fplog,"Hess2008b");
+      please_cite(fplog,"Spoel2005a");
+      please_cite(fplog,"Lindahl2001a");
+      please_cite(fplog,"Berendsen95a");
+  }
+  else if (!MASTER(cr) && bSepPot)
+  {
+      gmx_log_open(ftp2fn(efLOG,NFILE,fnm),cr,!bSepPot,Flags,&fplog);
+  }
+  else
+  {
+      fplog = NULL;
+  }
+
+  ddxyz[XX] = (int)(realddxyz[XX] + 0.5);
+  ddxyz[YY] = (int)(realddxyz[YY] + 0.5);
+  ddxyz[ZZ] = (int)(realddxyz[ZZ] + 0.5);
+
+  rc = mdrunner(&hw_opt, fplog,cr,NFILE,fnm,oenv,bVerbose,bCompact,
+                nstglobalcomm, ddxyz,dd_node_order,rdd,rconstr,
+                dddlb_opt[0],dlb_scale,ddcsx,ddcsy,ddcsz,
+                nbpu_opt[0],
+                nsteps,nstepout,resetstep,
+                nmultisim,repl_ex_nst,repl_ex_nex,repl_ex_seed,
+                pforce, cpt_period,max_hours,deviceOptions,Flags);
+
+  gmx_finalize_par();
+
+  if (MULTIMASTER(cr)) {
+      thanx(stderr);
+  }
+
+  /* Log file has to be closed in mdrunner if we are appending to it 
+     (fplog not set here) */
+  if (MASTER(cr) && !bAppendFiles) 
+  {
+      gmx_log_close(fplog);
+  }
+
+  return rc;
+}
+
diff --git a/src/contrib/openmm_gpu_utils.cu b/src/contrib/openmm_gpu_utils.cu
new file mode 100644 (file)
index 0000000..cf10dfb
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2010,2012 The GROMACS development team,
+ * check out http://www.gromacs.org for more information.
+ * Copyright (c) 2012, by the GROMACS development team, led by
+ * David van der Spoel, Berk Hess, 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "smalloc.h"
+#include "string2.h"
+#include "types/hw_info.h"
+
+#include "openmm_gpu_utils.h"
+#include "../../src/gmxlib/cuda_tools/cudautils.cuh"
+
+// TODO put this list into an external file and include it so that the list is easily accessible
+/*! List of supported GPUs. */
+static const char * const SupportedGPUs[] = {
+    /* GT400 */
+    "Geforce GTX 480",
+    "Geforce GTX 470",
+    "Geforce GTX 465",
+    "Geforce GTX 460",
+
+    "Tesla C2070",
+    "Tesla C2050",
+    "Tesla S2070",
+    "Tesla S2050",
+    "Tesla M2070",
+    "Tesla M2050",
+
+    "Quadro 5000",
+    "Quadro 6000",
+
+    /* GT200 */
+    "Geforce GTX 295",
+    "Geforce GTX 285",
+    "Geforce GTX 280",
+    "Geforce GTX 275",
+    "Geforce GTX 260",
+    "GeForce GTS 250",
+    "GeForce GTS 150",
+
+    "GeForce GTX 285M",
+    "GeForce GTX 280M",
+
+    "Tesla S1070",
+    "Tesla C1060",
+    "Tesla M1060",
+
+    "Quadro FX 5800",
+    "Quadro FX 4800",
+    "Quadro CX",
+    "Quadro Plex 2200 D2",
+    "Quadro Plex 2200 S4",
+
+    /* G90 */
+    "GeForce 9800 G", /* GX2, GTX, GTX+, GT */
+    "GeForce 9800M GTX",
+
+    "Quadro FX 4700",
+    "Quadro Plex 2100 D4"
+};
+
+/*! Number of supported GPUs */
+#define NB_GPUS (sizeof(SupportedGPUs)/sizeof(SupportedGPUs[0]))
+
+FUNC_QUALIFIER
+gmx_bool is_gmx_openmm_supported_gpu(int dev_id, char *gpu_name) FUNC_TERM_INT
+
+/*! 
+ * \brief Checks whether the GPU with the given name is supported in Gromacs-OpenMM.
+ * 
+ * \param[in] gpu_name  the name of the CUDA device
+ * \returns             TRUE if the device is supported, otherwise FALSE
+ */
+static bool is_gmx_openmm_supported_gpu_name(char *gpuName)
+{
+    size_t i;
+    for (i = 0; i < NB_GPUS; i++)
+    {
+        trim(gpuName);
+        if (gmx_strncasecmp(gpuName, SupportedGPUs[i], strlen(SupportedGPUs[i])) == 0)
+            return 1;
+    }
+    return 0;
+}
+
+/*! \brief Checks whether the GPU with the given device id is supported in Gromacs-OpenMM.
+ *
+ * \param[in] dev_id    the device id of the GPU or -1 if the device has already been selected
+ * \param[out] gpu_name Set to contain the name of the CUDA device, if NULL passed, no device name is set. 
+ * \returns             TRUE if the device is supported, otherwise FALSE
+ * 
+ */
+gmx_bool is_gmx_openmm_supported_gpu(int dev_id, char *gpu_name)
+{
+    cudaDeviceProp dev_prop;
+
+    if (debug) fprintf(debug, "Checking compatibility with device #%d, %s\n", dev_id, gpu_name);
+
+    if (do_sanity_checks(dev_id, &dev_prop) != 0)
+        return -1;
+
+    if (gpu_name != NULL)
+    { 
+        strcpy(gpu_name, dev_prop.name);
+    }
+    return is_gmx_openmm_supported_gpu_name(dev_prop.name);
+}
+
+
diff --git a/src/contrib/openmm_gpu_utils.h b/src/contrib/openmm_gpu_utils.h
new file mode 100644 (file)
index 0000000..c5874d6
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2010, The GROMACS development team,
+ * check out http://www.gromacs.org for more information.
+ * Copyright (c) 2012, by the GROMACS development team, led by
+ * David van der Spoel, Berk Hess, 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.
+ */
+
+#ifndef _OPENMM_GPU_UTILS_H_
+#define _OPENMM_GPU_UTILS_H_
+
+#include "types/simple.h"
+#include "types/hw_info.h"
+
+#define FUNC_TERM_INT {return -1;}
+#define FUNC_TERM_VOID {}
+#define FUNC_QUALIFIER static
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+FUNC_QUALIFIER
+gmx_bool is_gmx_openmm_supported_gpu(int dev_id, char *gpu_name) FUNC_TERM_INT
+
+#ifdef __cplusplus
+}
+#endif
+
+#undef FUNC_TERM_INT
+#undef FUNC_TERM_VOID
+#undef FUNC_QUALIFIER
+
+#endif /* _OPENMM_GPU_UTILS_H_ */
similarity index 99%
rename from src/programs/mdrun/openmm_wrapper.cpp
rename to src/contrib/openmm_wrapper.cpp
index 582cedc233aef07127e5236d05557b7cd48c2699..07f0ecaccee38b501aca88e200d92dde9ed10cda 100644 (file)
@@ -380,11 +380,11 @@ void GmxOpenMMPlatformOptions::print()
 class OpenMMData
 {
 public:
-    System* system;      //!< The system to simulate.
-    Context* context;   //!< The OpenMM context in which the simulation is carried out.
-    Integrator* integrator; //!< The integrator used in the simulation.
-    gmx_bool removeCM;          //!< If true, remove center of mass motion, false otherwise.
-    GmxOpenMMPlatformOptions *platformOpt; //!< Platform options.
+    System* system;      /*! The system to simulate. */
+    Context* context;   /*! The OpenMM context in which the simulation is carried out. */
+    Integrator* integrator; /*! The integrator used in the simulation. */
+    gmx_bool removeCM;          /*! If \true remove venter of motion, false otherwise. */
+    GmxOpenMMPlatformOptions *platformOpt; /*! Platform options. */
 };
 
 /*!
@@ -518,6 +518,7 @@ static void checkGmxOptions(FILE* fplog, GmxOpenMMPlatformOptions *opt,
                             t_inputrec *ir, gmx_localtop_t *top,
                             t_forcerec *fr, t_state *state)
 {
+    char    warn_buf[STRLEN];
     int     i, j, natoms;
     double  c6, c12;
     double  sigma_ij=0, sigma_ji=0, sigma_ii=0, sigma_jj=0, sigma_comb;
diff --git a/src/contrib/openmm_wrapper.h b/src/contrib/openmm_wrapper.h
new file mode 100644 (file)
index 0000000..7013426
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2010, The GROMACS development team,
+ * check out http://www.gromacs.org for more information.
+ * Copyright (c) 2012, by the GROMACS development team, led by
+ * David van der Spoel, Berk Hess, 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.
+ */
+
+#ifndef _OPENMM_WRAPPER_H_
+#define _OPENMM_WRAPPER_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+void* openmm_init(FILE *fplog, const char *platformOptStr,
+                    t_inputrec *ir,
+                    gmx_mtop_t *top_global, gmx_localtop_t *top,
+                    t_mdatoms *mdatoms, t_forcerec *fr, t_state *state);
+
+void openmm_take_one_step(void* data);
+
+void openmm_take_steps(void* data, int nsteps);
+
+void openmm_copy_state(void *data,
+                        t_state *state, double *time,
+                        rvec f[], gmx_enerdata_t *enerd,
+                        gmx_bool includePos, gmx_bool includeVel, gmx_bool includeForce, gmx_bool includeEnergy);
+
+void openmm_cleanup(FILE *fplog, void* data);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* _OPENMM_WRAPPER_H_ */
+
diff --git a/src/contrib/runner_openmm.c b/src/contrib/runner_openmm.c
new file mode 100644 (file)
index 0000000..a04b618
--- /dev/null
@@ -0,0 +1,1998 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2004, The GROMACS development team,
+ * check out http://www.gromacs.org for more information.
+ * Copyright (c) 2012, by the GROMACS development team, led by
+ * David van der Spoel, Berk Hess, 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.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_GETAFFINITY)
+#define _GNU_SOURCE
+#include <sched.h>
+#include <sys/syscall.h>
+#endif
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "typedefs.h"
+#include "smalloc.h"
+#include "sysstuff.h"
+#include "statutil.h"
+#include "mdrun.h"
+#include "md_logging.h"
+#include "md_support.h"
+#include "network.h"
+#include "pull.h"
+#include "names.h"
+#include "disre.h"
+#include "orires.h"
+#include "pme.h"
+#include "mdatoms.h"
+#include "repl_ex.h"
+#include "qmmm.h"
+#include "mpelogging.h"
+#include "domdec.h"
+#include "partdec.h"
+#include "coulomb.h"
+#include "constr.h"
+#include "mvdata.h"
+#include "checkpoint.h"
+#include "mtop_util.h"
+#include "sighandler.h"
+#include "tpxio.h"
+#include "txtdump.h"
+#include "gmx_detect_hardware.h"
+#include "gmx_omp_nthreads.h"
+#include "pull_rotation.h"
+#include "calc_verletbuf.h"
+#include "../mdlib/nbnxn_search.h"
+#include "../mdlib/nbnxn_consts.h"
+#include "gmx_fatal_collective.h"
+#include "membed.h"
+#include "md_openmm.h"
+#include "gmx_omp.h"
+
+#include "thread_mpi/threads.h"
+
+#ifdef GMX_LIB_MPI
+#include <mpi.h>
+#endif
+#ifdef GMX_THREAD_MPI
+#include "tmpi.h"
+#endif
+
+#ifdef GMX_FAHCORE
+#include "corewrap.h"
+#endif
+
+#include "gpu_utils.h"
+#include "nbnxn_cuda_data_mgmt.h"
+
+typedef struct { 
+    gmx_integrator_t *func;
+} gmx_intp_t;
+
+/* The array should match the eI array in include/types/enums.h */
+const gmx_intp_t integrator[eiNR] = { {do_md_openmm}, {do_md_openmm}, {do_md_openmm}, {do_md_openmm}, {do_md_openmm}, {do_md_openmm}, {do_md_openmm}, {do_md_openmm}, {do_md_openmm}, {do_md_openmm}, {do_md_openmm},{do_md_openmm}};
+
+gmx_large_int_t     deform_init_init_step_tpx;
+matrix              deform_init_box_tpx;
+#ifdef GMX_THREAD_MPI
+tMPI_Thread_mutex_t deform_init_box_mutex=TMPI_THREAD_MUTEX_INITIALIZER;
+#endif
+
+
+#ifdef GMX_THREAD_MPI
+struct mdrunner_arglist
+{
+    gmx_hw_opt_t *hw_opt;
+    FILE *fplog;
+    t_commrec *cr;
+    int nfile;
+    const t_filenm *fnm;
+    output_env_t oenv;
+    gmx_bool bVerbose;
+    gmx_bool bCompact;
+    int nstglobalcomm;
+    ivec ddxyz;
+    int dd_node_order;
+    real rdd;
+    real rconstr;
+    const char *dddlb_opt;
+    real dlb_scale;
+    const char *ddcsx;
+    const char *ddcsy;
+    const char *ddcsz;
+    const char *nbpu_opt;
+    int nsteps_cmdline;
+    int nstepout;
+    int resetstep;
+    int nmultisim;
+    int repl_ex_nst;
+    int repl_ex_nex;
+    int repl_ex_seed;
+    real pforce;
+    real cpt_period;
+    real max_hours;
+    const char *deviceOptions;
+    unsigned long Flags;
+    int ret; /* return value */
+};
+
+
+/* The function used for spawning threads. Extracts the mdrunner() 
+   arguments from its one argument and calls mdrunner(), after making
+   a commrec. */
+static void mdrunner_start_fn(void *arg)
+{
+    struct mdrunner_arglist *mda=(struct mdrunner_arglist*)arg;
+    struct mdrunner_arglist mc=*mda; /* copy the arg list to make sure 
+                                        that it's thread-local. This doesn't
+                                        copy pointed-to items, of course,
+                                        but those are all const. */
+    t_commrec *cr;  /* we need a local version of this */
+    FILE *fplog=NULL;
+    t_filenm *fnm;
+
+    fnm = dup_tfn(mc.nfile, mc.fnm);
+
+    cr = init_par_threads(mc.cr);
+
+    if (MASTER(cr))
+    {
+        fplog=mc.fplog;
+    }
+
+    mda->ret=mdrunner(mc.hw_opt, fplog, cr, mc.nfile, fnm, mc.oenv, 
+                      mc.bVerbose, mc.bCompact, mc.nstglobalcomm, 
+                      mc.ddxyz, mc.dd_node_order, mc.rdd,
+                      mc.rconstr, mc.dddlb_opt, mc.dlb_scale, 
+                      mc.ddcsx, mc.ddcsy, mc.ddcsz,
+                      mc.nbpu_opt,
+                      mc.nsteps_cmdline, mc.nstepout, mc.resetstep,
+                      mc.nmultisim, mc.repl_ex_nst, mc.repl_ex_nex, mc.repl_ex_seed, mc.pforce, 
+                      mc.cpt_period, mc.max_hours, mc.deviceOptions, mc.Flags);
+}
+
+/* called by mdrunner() to start a specific number of threads (including 
+   the main thread) for thread-parallel runs. This in turn calls mdrunner()
+   for each thread. 
+   All options besides nthreads are the same as for mdrunner(). */
+static t_commrec *mdrunner_start_threads(gmx_hw_opt_t *hw_opt, 
+              FILE *fplog,t_commrec *cr,int nfile, 
+              const t_filenm fnm[], const output_env_t oenv, gmx_bool bVerbose,
+              gmx_bool bCompact, int nstglobalcomm,
+              ivec ddxyz,int dd_node_order,real rdd,real rconstr,
+              const char *dddlb_opt,real dlb_scale,
+              const char *ddcsx,const char *ddcsy,const char *ddcsz,
+              const char *nbpu_opt,
+              int nsteps_cmdline, int nstepout,int resetstep,
+              int nmultisim,int repl_ex_nst,int repl_ex_nex, int repl_ex_seed,
+              real pforce,real cpt_period, real max_hours, 
+              const char *deviceOptions, unsigned long Flags)
+{
+    int ret;
+    struct mdrunner_arglist *mda;
+    t_commrec *crn; /* the new commrec */
+    t_filenm *fnmn;
+
+    /* first check whether we even need to start tMPI */
+    if (hw_opt->nthreads_tmpi < 2)
+    {
+        return cr;
+    }
+
+    /* a few small, one-time, almost unavoidable memory leaks: */
+    snew(mda,1);
+    fnmn=dup_tfn(nfile, fnm);
+
+    /* fill the data structure to pass as void pointer to thread start fn */
+    mda->hw_opt=hw_opt;
+    mda->fplog=fplog;
+    mda->cr=cr;
+    mda->nfile=nfile;
+    mda->fnm=fnmn;
+    mda->oenv=oenv;
+    mda->bVerbose=bVerbose;
+    mda->bCompact=bCompact;
+    mda->nstglobalcomm=nstglobalcomm;
+    mda->ddxyz[XX]=ddxyz[XX];
+    mda->ddxyz[YY]=ddxyz[YY];
+    mda->ddxyz[ZZ]=ddxyz[ZZ];
+    mda->dd_node_order=dd_node_order;
+    mda->rdd=rdd;
+    mda->rconstr=rconstr;
+    mda->dddlb_opt=dddlb_opt;
+    mda->dlb_scale=dlb_scale;
+    mda->ddcsx=ddcsx;
+    mda->ddcsy=ddcsy;
+    mda->ddcsz=ddcsz;
+    mda->nbpu_opt=nbpu_opt;
+    mda->nsteps_cmdline=nsteps_cmdline;
+    mda->nstepout=nstepout;
+    mda->resetstep=resetstep;
+    mda->nmultisim=nmultisim;
+    mda->repl_ex_nst=repl_ex_nst;
+    mda->repl_ex_nex=repl_ex_nex;
+    mda->repl_ex_seed=repl_ex_seed;
+    mda->pforce=pforce;
+    mda->cpt_period=cpt_period;
+    mda->max_hours=max_hours;
+    mda->deviceOptions=deviceOptions;
+    mda->Flags=Flags;
+
+    /* now spawn new threads that start mdrunner_start_fn(), while 
+       the main thread returns */
+    ret=tMPI_Init_fn(TRUE, hw_opt->nthreads_tmpi,
+                     (hw_opt->bThreadPinning ? TMPI_AFFINITY_ALL_CORES : TMPI_AFFINITY_NONE),
+                     mdrunner_start_fn, (void*)(mda) );
+    if (ret!=TMPI_SUCCESS)
+        return NULL;
+
+    /* make a new comm_rec to reflect the new situation */
+    crn=init_par_threads(cr);
+    return crn;
+}
+
+
+static int get_tmpi_omp_thread_division(const gmx_hw_info_t *hwinfo,
+                                        const gmx_hw_opt_t *hw_opt,
+                                        int nthreads_tot,
+                                        int ngpu)
+{
+    int nthreads_tmpi;
+
+    /* There are no separate PME nodes here, as we ensured in
+     * check_and_update_hw_opt that nthreads_tmpi>0 with PME nodes
+     * and a conditional ensures we would not have ended up here.
+     * Note that separate PME nodes might be switched on later.
+     */
+    if (ngpu > 0)
+    {
+        nthreads_tmpi = ngpu;
+        if (nthreads_tot > 0 && nthreads_tot < nthreads_tmpi)
+        {
+            nthreads_tmpi = nthreads_tot;
+        }
+    }
+    else if (hw_opt->nthreads_omp > 0)
+    {
+        /* Here we could oversubscribe, when we do, we issue a warning later */
+        nthreads_tmpi = max(1,nthreads_tot/hw_opt->nthreads_omp);
+    }
+    else
+    {
+        /* TODO choose nthreads_omp based on hardware topology
+           when we have a hardware topology detection library */
+        /* In general, when running up to 4 threads, OpenMP should be faster.
+         * Note: on AMD Bulldozer we should avoid running OpenMP over two dies.
+         * On Intel>=Nehalem running OpenMP on a single CPU is always faster,
+         * even on two CPUs it's usually faster (but with many OpenMP threads
+         * it could be faster not to use HT, currently we always use HT).
+         * On Nehalem/Westmere we want to avoid running 16 threads over
+         * two CPUs with HT, so we need a limit<16; thus we use 12.
+         * A reasonable limit for Intel Sandy and Ivy bridge,
+         * not knowing the topology, is 16 threads.
+         */
+        const int nthreads_omp_always_faster             =  4;
+        const int nthreads_omp_always_faster_Nehalem     = 12;
+        const int nthreads_omp_always_faster_SandyBridge = 16;
+        const int first_model_Nehalem     = 0x1A;
+        const int first_model_SandyBridge = 0x2A;
+        gmx_bool bIntel_Family6;
+
+        bIntel_Family6 =
+            (gmx_cpuid_vendor(hwinfo->cpuid_info) == GMX_CPUID_VENDOR_INTEL &&
+             gmx_cpuid_family(hwinfo->cpuid_info) == 6);
+
+        if (nthreads_tot <= nthreads_omp_always_faster ||
+            (bIntel_Family6 &&
+             ((gmx_cpuid_model(hwinfo->cpuid_info) >= nthreads_omp_always_faster_Nehalem && nthreads_tot <= nthreads_omp_always_faster_Nehalem) ||
+              (gmx_cpuid_model(hwinfo->cpuid_info) >= nthreads_omp_always_faster_SandyBridge && nthreads_tot <= nthreads_omp_always_faster_SandyBridge))))
+        {
+            /* Use pure OpenMP parallelization */
+            nthreads_tmpi = 1;
+        }
+        else
+        {
+            /* Don't use OpenMP parallelization */
+            nthreads_tmpi = nthreads_tot;
+        }
+    }
+
+    return nthreads_tmpi;
+}
+
+
+/* Get the number of threads to use for thread-MPI based on how many
+ * were requested, which algorithms we're using,
+ * and how many particles there are.
+ * At the point we have already called check_and_update_hw_opt.
+ * Thus all options should be internally consistent and consistent
+ * with the hardware, except that ntmpi could be larger than #GPU.
+ */
+static int get_nthreads_mpi(gmx_hw_info_t *hwinfo,
+                            gmx_hw_opt_t *hw_opt,
+                            t_inputrec *inputrec, gmx_mtop_t *mtop,
+                            const t_commrec *cr,
+                            FILE *fplog)
+{
+    int nthreads_hw,nthreads_tot_max,nthreads_tmpi,nthreads_new,ngpu;
+    int min_atoms_per_mpi_thread;
+    char *env;
+    char sbuf[STRLEN];
+    gmx_bool bCanUseGPU;
+
+    if (hw_opt->nthreads_tmpi > 0)
+    {
+        /* Trivial, return right away */
+        return hw_opt->nthreads_tmpi;
+    }
+
+    nthreads_hw = hwinfo->nthreads_hw_avail;
+
+    /* How many total (#tMPI*#OpenMP) threads can we start? */ 
+    if (hw_opt->nthreads_tot > 0)
+    {
+        nthreads_tot_max = hw_opt->nthreads_tot;
+    }
+    else
+    {
+        nthreads_tot_max = nthreads_hw;
+    }
+
+    bCanUseGPU = (inputrec->cutoff_scheme == ecutsVERLET && hwinfo->bCanUseGPU);
+    if (bCanUseGPU)
+    {
+        ngpu = hwinfo->gpu_info.ncuda_dev_use;
+    }
+    else
+    {
+        ngpu = 0;
+    }
+
+    nthreads_tmpi =
+        get_tmpi_omp_thread_division(hwinfo,hw_opt,nthreads_tot_max,ngpu);
+
+    if (inputrec->eI == eiNM || EI_TPI(inputrec->eI))
+    {
+        /* Steps are divided over the nodes iso splitting the atoms */
+        min_atoms_per_mpi_thread = 0;
+    }
+    else
+    {
+        if (bCanUseGPU)
+        {
+            min_atoms_per_mpi_thread = MIN_ATOMS_PER_GPU;
+        }
+        else
+        {
+            min_atoms_per_mpi_thread = MIN_ATOMS_PER_MPI_THREAD;
+        }
+    }
+
+    /* Check if an algorithm does not support parallel simulation.  */
+    if (nthreads_tmpi != 1 &&
+        ( inputrec->eI == eiLBFGS ||
+          inputrec->coulombtype == eelEWALD ) )
+    {
+        nthreads_tmpi = 1;
+
+        md_print_warn(cr,fplog,"The integration or electrostatics algorithm doesn't support parallel runs. Using a single thread-MPI thread.\n");
+        if (hw_opt->nthreads_tmpi > nthreads_tmpi)
+        {
+            gmx_fatal(FARGS,"You asked for more than 1 thread-MPI thread, but an algorithm doesn't support that");
+        }
+    }
+    else if (mtop->natoms/nthreads_tmpi < min_atoms_per_mpi_thread)
+    {
+        /* the thread number was chosen automatically, but there are too many
+           threads (too few atoms per thread) */
+        nthreads_new = max(1,mtop->natoms/min_atoms_per_mpi_thread);
+
+        /* Avoid partial use of Hyper-Threading */
+        if (gmx_cpuid_x86_smt(hwinfo->cpuid_info) == GMX_CPUID_X86_SMT_ENABLED &&
+            nthreads_new > nthreads_hw/2 && nthreads_new < nthreads_hw)
+        {
+            nthreads_new = nthreads_hw/2;
+        }
+
+        /* Avoid large prime numbers in the thread count */
+        if (nthreads_new >= 6)
+        {
+            /* Use only 6,8,10 with additional factors of 2 */
+            int fac;
+
+            fac = 2;
+            while (3*fac*2 <= nthreads_new)
+            {
+                fac *= 2;
+            }
+
+            nthreads_new = (nthreads_new/fac)*fac;
+        }
+        else
+        {
+            /* Avoid 5 */
+            if (nthreads_new == 5)
+            {
+                nthreads_new = 4;
+            }
+        }
+
+        nthreads_tmpi = nthreads_new;
+
+        fprintf(stderr,"\n");
+        fprintf(stderr,"NOTE: Parallelization is limited by the small number of atoms,\n");
+        fprintf(stderr,"      only starting %d thread-MPI threads.\n",nthreads_tmpi);
+        fprintf(stderr,"      You can use the -nt and/or -ntmpi option to optimize the number of threads.\n\n");
+    }
+
+    return nthreads_tmpi;
+}
+#endif /* GMX_THREAD_MPI */
+
+
+/* Environment variable for setting nstlist */
+static const char*  NSTLIST_ENVVAR          =  "GMX_NSTLIST";
+/* Try to increase nstlist when using a GPU with nstlist less than this */
+static const int    NSTLIST_GPU_ENOUGH      = 20;
+/* Increase nstlist until the non-bonded cost increases more than this factor */
+static const float  NBNXN_GPU_LIST_OK_FAC   = 1.25;
+/* Don't increase nstlist beyond a non-bonded cost increases of this factor */
+static const float  NBNXN_GPU_LIST_MAX_FAC  = 1.40;
+
+/* Try to increase nstlist when running on a GPU */
+static void increase_nstlist(FILE *fp,t_commrec *cr,
+                             t_inputrec *ir,const gmx_mtop_t *mtop,matrix box)
+{
+    char *env;
+    int  nstlist_orig,nstlist_prev;
+    verletbuf_list_setup_t ls;
+    real rlist_inc,rlist_ok,rlist_max,rlist_new,rlist_prev;
+    int  i;
+    t_state state_tmp;
+    gmx_bool bBox,bDD,bCont;
+    const char *nstl_fmt="\nFor optimal performance with a GPU nstlist (now %d) should be larger.\nThe optimum depends on your CPU and GPU resources.\nYou might want to try several nstlist values.\n";
+    const char *vbd_err="Can not increase nstlist for GPU run because verlet-buffer-drift is not set or used";
+    const char *box_err="Can not increase nstlist for GPU run because the box is too small";
+    const char *dd_err ="Can not increase nstlist for GPU run because of domain decomposition limitations";
+    char buf[STRLEN];
+
+    /* Number of + nstlist alternative values to try when switching  */
+    const int nstl[]={ 20, 25, 40, 50 };
+#define NNSTL  sizeof(nstl)/sizeof(nstl[0])
+
+    env = getenv(NSTLIST_ENVVAR);
+    if (env == NULL)
+    {
+        if (fp != NULL)
+        {
+            fprintf(fp,nstl_fmt,ir->nstlist);
+        }
+    }
+
+    if (ir->verletbuf_drift == 0)
+    {
+        gmx_fatal(FARGS,"You are using an old tpr file with a GPU, please generate a new tpr file with an up to date version of grompp");
+    }
+
+    if (ir->verletbuf_drift < 0)
+    {
+        if (MASTER(cr))
+        {
+            fprintf(stderr,"%s\n",vbd_err);
+        }
+        if (fp != NULL)
+        {
+            fprintf(fp,"%s\n",vbd_err);
+        }
+
+        return;
+    }
+
+    nstlist_orig = ir->nstlist;
+    if (env != NULL)
+    {
+        sprintf(buf,"Getting nstlist from environment variable GMX_NSTLIST=%s",env);
+        if (MASTER(cr))
+        {
+            fprintf(stderr,"%s\n",buf);
+        }
+        if (fp != NULL)
+        {
+            fprintf(fp,"%s\n",buf);
+        }
+        sscanf(env,"%d",&ir->nstlist);
+    }
+
+    verletbuf_get_list_setup(TRUE,&ls);
+
+    /* Allow rlist to make the list double the size of the cut-off sphere */
+    rlist_inc = nbnxn_get_rlist_effective_inc(NBNXN_GPU_CLUSTER_SIZE,mtop->natoms/det(box));
+    rlist_ok  = (max(ir->rvdw,ir->rcoulomb) + rlist_inc)*pow(NBNXN_GPU_LIST_OK_FAC,1.0/3.0) - rlist_inc;
+    rlist_max = (max(ir->rvdw,ir->rcoulomb) + rlist_inc)*pow(NBNXN_GPU_LIST_MAX_FAC,1.0/3.0) - rlist_inc;
+    if (debug)
+    {
+        fprintf(debug,"GPU nstlist tuning: rlist_inc %.3f rlist_max %.3f\n",
+                rlist_inc,rlist_max);
+    }
+
+    i = 0;
+    nstlist_prev = nstlist_orig;
+    rlist_prev   = ir->rlist;
+    do
+    {
+        if (env == NULL)
+        {
+            ir->nstlist = nstl[i];
+        }
+
+        /* Set the pair-list buffer size in ir */
+        calc_verlet_buffer_size(mtop,det(box),ir,ir->verletbuf_drift,&ls,
+                                NULL,&rlist_new);
+
+        /* Does rlist fit in the box? */
+        bBox = (sqr(rlist_new) < max_cutoff2(ir->ePBC,box));
+        bDD  = TRUE;
+        if (bBox && DOMAINDECOMP(cr))
+        {
+            /* Check if rlist fits in the domain decomposition */
+            if (inputrec2nboundeddim(ir) < DIM)
+            {
+                gmx_incons("Changing nstlist with domain decomposition and unbounded dimensions is not implemented yet");
+            }
+            copy_mat(box,state_tmp.box);
+            bDD = change_dd_cutoff(cr,&state_tmp,ir,rlist_new);
+        }
+
+        bCont = FALSE;
+
+        if (env == NULL)
+        {
+            if (bBox && bDD && rlist_new <= rlist_max)
+            {
+                /* Increase nstlist */
+                nstlist_prev = ir->nstlist;
+                rlist_prev   = rlist_new;
+                bCont = (i+1 < NNSTL && rlist_new < rlist_ok);
+            }
+            else
+            {
+                /* Stick with the previous nstlist */
+                ir->nstlist = nstlist_prev;
+                rlist_new   = rlist_prev;
+                bBox = TRUE;
+                bDD  = TRUE;
+            }
+        }
+
+        i++;
+    }
+    while (bCont);
+
+    if (!bBox || !bDD)
+    {
+        gmx_warning(!bBox ? box_err : dd_err);
+        if (fp != NULL)
+        {
+            fprintf(fp,"\n%s\n",bBox ? box_err : dd_err);
+        }
+        ir->nstlist = nstlist_orig;
+    }
+    else if (ir->nstlist != nstlist_orig || rlist_new != ir->rlist)
+    {
+        sprintf(buf,"Changing nstlist from %d to %d, rlist from %g to %g",
+                nstlist_orig,ir->nstlist,
+                ir->rlist,rlist_new);
+        if (MASTER(cr))
+        {
+            fprintf(stderr,"%s\n\n",buf);
+        }
+        if (fp != NULL)
+        {
+            fprintf(fp,"%s\n\n",buf);
+        }
+        ir->rlist     = rlist_new;
+        ir->rlistlong = rlist_new;
+    }
+}
+
+static void prepare_verlet_scheme(FILE *fplog,
+                                  gmx_hw_info_t *hwinfo,
+                                  t_commrec *cr,
+                                  gmx_hw_opt_t *hw_opt,
+                                  const char *nbpu_opt,
+                                  t_inputrec *ir,
+                                  const gmx_mtop_t *mtop,
+                                  matrix box,
+                                  gmx_bool *bUseGPU)
+{
+    /* Here we only check for GPU usage on the MPI master process,
+     * as here we don't know how many GPUs we will use yet.
+     * We check for a GPU on all processes later.
+     */
+    *bUseGPU = hwinfo->bCanUseGPU || (getenv("GMX_EMULATE_GPU") != NULL);
+
+    if (ir->verletbuf_drift > 0)
+    {
+        /* Update the Verlet buffer size for the current run setup */
+        verletbuf_list_setup_t ls;
+        real rlist_new;
+
+        /* Here we assume CPU acceleration is on. But as currently
+         * calc_verlet_buffer_size gives the same results for 4x8 and 4x4
+         * and 4x2 gives a larger buffer than 4x4, this is ok.
+         */
+        verletbuf_get_list_setup(*bUseGPU,&ls);
+
+        calc_verlet_buffer_size(mtop,det(box),ir,
+                                ir->verletbuf_drift,&ls,
+                                NULL,&rlist_new);
+        if (rlist_new != ir->rlist)
+        {
+            if (fplog != NULL)
+            {
+                fprintf(fplog,"\nChanging rlist from %g to %g for non-bonded %dx%d atom kernels\n\n",
+                        ir->rlist,rlist_new,
+                        ls.cluster_size_i,ls.cluster_size_j);
+            }
+            ir->rlist     = rlist_new;
+            ir->rlistlong = rlist_new;
+        }
+    }
+
+    /* With GPU or emulation we should check nstlist for performance */
+    if ((EI_DYNAMICS(ir->eI) &&
+         *bUseGPU &&
+         ir->nstlist < NSTLIST_GPU_ENOUGH) ||
+        getenv(NSTLIST_ENVVAR) != NULL)
+    {
+        /* Choose a better nstlist */
+        increase_nstlist(fplog,cr,ir,mtop,box);
+    }
+}
+
+static void convert_to_verlet_scheme(FILE *fplog,
+                                     t_inputrec *ir,
+                                     gmx_mtop_t *mtop,real box_vol)
+{
+    char *conv_mesg="Converting input file with group cut-off scheme to the Verlet cut-off scheme";
+
+    md_print_warn(NULL,fplog,"%s\n",conv_mesg);
+
+    ir->cutoff_scheme   = ecutsVERLET;
+    ir->verletbuf_drift = 0.005;
+
+    if (ir->rcoulomb != ir->rvdw)
+    {
+        gmx_fatal(FARGS,"The VdW and Coulomb cut-offs are different, whereas the Verlet scheme only supports equal cut-offs");
+    }
+
+    if (ir->vdwtype == evdwUSER || EEL_USER(ir->coulombtype))
+    {
+        gmx_fatal(FARGS,"User non-bonded potentials are not (yet) supported with the Verlet scheme");
+    }
+    else if (EVDW_SWITCHED(ir->vdwtype) || EEL_SWITCHED(ir->coulombtype))
+    {
+        md_print_warn(NULL,fplog,"Converting switched or shifted interactions to a shifted potential (without force shift), this will lead to slightly different interaction potentials");
+
+        if (EVDW_SWITCHED(ir->vdwtype))
+        {
+            ir->vdwtype = evdwCUT;
+        }
+        if (EEL_SWITCHED(ir->coulombtype))
+        {
+            if (EEL_FULL(ir->coulombtype))
+            {
+                /* With full electrostatic only PME can be switched */
+                ir->coulombtype = eelPME;
+            }
+            else
+            {
+                md_print_warn(NULL,fplog,"NOTE: Replacing %s electrostatics with reaction-field with epsilon-rf=inf\n",eel_names[ir->coulombtype]);
+                ir->coulombtype = eelRF;
+                ir->epsilon_rf  = 0.0;
+            }
+        }
+
+        /* We set the target energy drift to a small number.
+         * Note that this is only for testing. For production the user
+         * should think about this and set the mdp options.
+         */
+        ir->verletbuf_drift = 1e-4;
+    }
+
+    if (inputrec2nboundeddim(ir) != 3)
+    {
+        gmx_fatal(FARGS,"Can only convert old tpr files to the Verlet cut-off scheme with 3D pbc");
+    }
+
+    if (ir->efep != efepNO || ir->implicit_solvent != eisNO)
+    {
+        gmx_fatal(FARGS,"Will not convert old tpr files to the Verlet cut-off scheme with free-energy calculations or implicit solvent");
+    }
+
+    if (EI_DYNAMICS(ir->eI) && !(EI_MD(ir->eI) && ir->etc == etcNO))
+    {
+        verletbuf_list_setup_t ls;
+
+        verletbuf_get_list_setup(FALSE,&ls);
+        calc_verlet_buffer_size(mtop,box_vol,ir,ir->verletbuf_drift,&ls,
+                                NULL,&ir->rlist);
+    }
+    else
+    {
+        ir->verletbuf_drift = -1;
+        ir->rlist           = 1.05*max(ir->rvdw,ir->rcoulomb);
+    }
+
+    gmx_mtop_remove_chargegroups(mtop);
+}
+
+/* Check the process affinity mask. If it is non-zero, something
+ * else has set the affinity, and mdrun should honor that and
+ * not attempt to do its own thread pinning.
+ *
+ * This function should be called twice. Once before the OpenMP
+ * library gets initialized with bAfterOpenMPInit=FALSE (which will
+ * detect affinity set by external tools like taskset), and again
+ * later, after the OpenMP initialization, with bAfterOpenMPInit=TRUE
+ * (which will detect affinity changes made by the OpenMP library).
+ *
+ * Note that this will only work on Linux, because we use a GNU
+ * feature. */
+static void check_cpu_affinity_set(FILE *fplog, const t_commrec *cr,
+                                   gmx_hw_opt_t *hw_opt, int ncpus,
+                                   gmx_bool bAfterOpenmpInit)
+{
+#ifdef HAVE_SCHED_GETAFFINITY
+    cpu_set_t mask_current;
+    int       i, ret, cpu_count, cpu_set;
+    gmx_bool  bAllSet;
+
+    assert(hw_opt);
+    if (!hw_opt->bThreadPinning)
+    {
+        /* internal affinity setting is off, don't bother checking process affinity */
+        return;
+    }
+
+    CPU_ZERO(&mask_current);
+    if ((ret = sched_getaffinity(0, sizeof(cpu_set_t), &mask_current)) != 0)
+    {
+        /* failed to query affinity mask, will just return */
+        if (debug)
+        {
+            fprintf(debug, "Failed to query affinity mask (error %d)", ret);
+        }
+        return;
+    }
+
+    /* Before proceeding with the actual check, make sure that the number of
+     * detected CPUs is >= the CPUs in the current set.
+     * We need to check for CPU_COUNT as it was added only in glibc 2.6. */
+#ifdef CPU_COUNT
+    if (ncpus < CPU_COUNT(&mask_current))
+    {
+        if (debug)
+        {
+            fprintf(debug, "%d CPUs detected, but %d was returned by CPU_COUNT",
+                    ncpus, CPU_COUNT(&mask_current));
+        }
+        return;
+    }
+#endif /* CPU_COUNT */
+
+    bAllSet = TRUE;
+    for (i = 0; (i < ncpus && i < CPU_SETSIZE); i++)
+    {
+        bAllSet = bAllSet && (CPU_ISSET(i, &mask_current) != 0);
+    }
+
+    if (!bAllSet)
+    {
+        if (!bAfterOpenmpInit)
+        {
+            md_print_warn(cr, fplog,
+                          "%s detected a non-default process affinity, "
+                          "so it will not attempt to pin its threads", ShortProgram());
+        }
+        else
+        {
+            md_print_warn(cr, fplog,
+                          "%s detected a non-default process affinity, "
+                          "probably set by the OpenMP library, "
+                          "so it will not attempt to pin its threads", ShortProgram());
+        }
+        hw_opt->bThreadPinning = FALSE;
+
+        if (debug)
+        {
+            fprintf(debug, "Non-default affinity mask found, mdrun will not pin threads\n");
+        }
+    }
+    else
+    {
+        if (debug)
+        {
+            fprintf(debug, "Default affinity mask found\n");
+        }
+    }
+#endif /* HAVE_SCHED_GETAFFINITY */
+}
+
+/* Set CPU affinity. Can be important for performance.
+   On some systems (e.g. Cray) CPU Affinity is set by default.
+   But default assigning doesn't work (well) with only some ranks
+   having threads. This causes very low performance.
+   External tools have cumbersome syntax for setting affinity
+   in the case that only some ranks have threads.
+   Thus it is important that GROMACS sets the affinity internally
+   if only PME is using threads.
+*/
+static void set_cpu_affinity(FILE *fplog,
+                             const t_commrec *cr,
+                             gmx_hw_opt_t *hw_opt,
+                             int nthreads_pme,
+                             const gmx_hw_info_t *hwinfo,
+                             const t_inputrec *inputrec)
+{
+#if defined GMX_THREAD_MPI
+    /* With the number of TMPI threads equal to the number of cores
+     * we already pinned in thread-MPI, so don't pin again here.
+     */
+    if (hw_opt->nthreads_tmpi == tMPI_Thread_get_hw_number())
+    {
+        return;
+    }
+#endif
+
+#ifndef __APPLE__
+    /* If the tMPI thread affinity setting is not supported encourage the user
+     * to report it as it's either a bug or an exotic platform which we might
+     * want to support. */
+    if (tMPI_Thread_setaffinity_support() != TMPI_SETAFFINITY_SUPPORT_YES)
+    {
+        md_print_warn(NULL, fplog,
+                      "Can not set thread affinities on the current plarform. On NUMA systems this\n"
+                      "can cause performance degradation. If you think your platform should support\n"
+                      "setting affinities, contact the GROMACS developers.");
+        return;
+    }
+#endif /* __APPLE__ */
+
+    if (hw_opt->bThreadPinning)
+    {
+        int nth_affinity_set, thread_id_node, thread_id,
+            nthread_local, nthread_node, nthread_hw_max, nphyscore;
+        int offset;
+        char *env;
+
+        /* threads on this MPI process or TMPI thread */
+        if (cr->duty & DUTY_PP)
+        {
+            nthread_local = gmx_omp_nthreads_get(emntNonbonded);
+        }
+        else
+        {
+            nthread_local = gmx_omp_nthreads_get(emntPME);
+        }
+
+        /* map the current process to cores */
+        thread_id_node = 0;
+        nthread_node = nthread_local;
+#ifdef GMX_MPI
+        if (PAR(cr) || MULTISIM(cr))
+        {
+            /* We need to determine a scan of the thread counts in this
+             * compute node.
+             */
+            MPI_Comm comm_intra;
+
+            MPI_Comm_split(MPI_COMM_WORLD,gmx_hostname_num(),cr->rank_intranode,
+                           &comm_intra);
+            MPI_Scan(&nthread_local,&thread_id_node,1,MPI_INT,MPI_SUM,comm_intra);
+            /* MPI_Scan is inclusive, but here we need exclusive */
+            thread_id_node -= nthread_local;
+            /* Get the total number of threads on this physical node */
+            MPI_Allreduce(&nthread_local,&nthread_node,1,MPI_INT,MPI_SUM,comm_intra);
+            MPI_Comm_free(&comm_intra);
+        }
+#endif
+
+        offset = 0;
+        if (hw_opt->core_pinning_offset > 0)
+        {
+            offset = hw_opt->core_pinning_offset;
+            if (SIMMASTER(cr))
+            {
+                fprintf(stderr, "Applying core pinning offset %d\n", offset);
+            }
+            if (fplog)
+            {
+                fprintf(fplog, "Applying core pinning offset %d\n", offset);
+            }
+        }
+
+        /* With Intel Hyper-Threading enabled, we want to pin consecutive
+         * threads to physical cores when using more threads than physical
+         * cores or when the user requests so.
+         */
+        nthread_hw_max = hwinfo->nthreads_hw_avail;
+        nphyscore = -1;
+        if (hw_opt->bPinHyperthreading ||
+            (gmx_cpuid_x86_smt(hwinfo->cpuid_info) == GMX_CPUID_X86_SMT_ENABLED &&
+             nthread_node > nthread_hw_max/2 && getenv("GMX_DISABLE_PINHT") == NULL))
+        {
+            if (gmx_cpuid_x86_smt(hwinfo->cpuid_info) != GMX_CPUID_X86_SMT_ENABLED)
+            {
+                /* We print to stderr on all processes, as we might have
+                 * different settings on different physical nodes.
+                 */
+                if (gmx_cpuid_vendor(hwinfo->cpuid_info) != GMX_CPUID_VENDOR_INTEL)
+                {
+                    md_print_warn(NULL, fplog, "Pinning for Hyper-Threading layout requested, "
+                                  "but non-Intel CPU detected (vendor: %s)\n",
+                                  gmx_cpuid_vendor_string[gmx_cpuid_vendor(hwinfo->cpuid_info)]);
+                }
+                else
+                {
+                    md_print_warn(NULL, fplog, "Pinning for Hyper-Threading layout requested, "
+                                  "but the CPU detected does not have Intel Hyper-Threading support "
+                                  "(or it is turned off)\n");
+                }
+            }
+            nphyscore = nthread_hw_max/2;
+
+            if (SIMMASTER(cr))
+            {
+                fprintf(stderr, "Pinning to Hyper-Threading cores with %d physical cores in a compute node\n",
+                        nphyscore);
+            }
+            if (fplog)
+            {
+                fprintf(fplog, "Pinning to Hyper-Threading cores with %d physical cores in a compute node\n",
+                        nphyscore);
+            }
+        }
+
+        /* Set the per-thread affinity. In order to be able to check the success
+         * of affinity settings, we will set nth_affinity_set to 1 on threads
+         * where the affinity setting succeded and to 0 where it failed.
+         * Reducing these 0/1 values over the threads will give the total number
+         * of threads on which we succeeded.
+         */
+         nth_affinity_set = 0;
+#pragma omp parallel firstprivate(thread_id_node) num_threads(nthread_local) \
+                     reduction(+:nth_affinity_set)
+        {
+            int      core;
+            gmx_bool setaffinity_ret;
+
+            thread_id       = gmx_omp_get_thread_num();
+            thread_id_node += thread_id;
+            if (nphyscore <= 0)
+            {
+                core = offset + thread_id_node;
+            }
+            else
+            {
+                /* Lock pairs of threads to the same hyperthreaded core */
+                core = offset + thread_id_node/2 + (thread_id_node % 2)*nphyscore;
+            }
+
+            setaffinity_ret = tMPI_Thread_setaffinity_single(tMPI_Thread_self(), core);
+
+            /* store the per-thread success-values of the setaffinity */
+            nth_affinity_set = (setaffinity_ret == 0);
+
+            if (debug)
+            {
+                fprintf(debug, "On rank %2d, thread %2d, core %2d the affinity setting returned %d\n",
+                        cr->nodeid, gmx_omp_get_thread_num(), core, setaffinity_ret);
+            }
+        }
+
+        if (nth_affinity_set > nthread_local)
+        {
+            char msg[STRLEN];
+
+            sprintf(msg, "Looks like we have set affinity for more threads than "
+                    "we have (%d > %d)!\n", nth_affinity_set, nthread_local);
+            gmx_incons(msg);
+        }
+        else
+        {
+            /* check & warn if some threads failed to set their affinities */
+            if (nth_affinity_set != nthread_local)
+            {
+                char sbuf1[STRLEN], sbuf2[STRLEN];
+
+                /* sbuf1 contains rank info, while sbuf2 OpenMP thread info */
+                sbuf1[0] = sbuf2[0] = '\0';
+#ifdef GMX_MPI
+#ifdef GMX_THREAD_MPI
+                sprintf(sbuf1, "In thread-MPI thread #%d: ", cr->nodeid);
+#else /* GMX_LIB_MPI */
+                sprintf(sbuf1, "In MPI process #%d: ", cr->nodeid);
+#endif
+#endif /* GMX_MPI */
+
+                if (nthread_local > 1)
+                {
+                    sprintf(sbuf2, "of %d/%d thread%s ",
+                            nthread_local - nth_affinity_set, nthread_local,
+                            (nthread_local - nth_affinity_set) > 1 ? "s" : "");
+                }
+
+                md_print_warn(NULL, fplog,
+                              "NOTE: %sAffinity setting %sfailed.\n"
+                              "      This can cause performance degradation!",
+                              sbuf1, sbuf2);
+            }
+        }
+    }
+}
+
+
+static void check_and_update_hw_opt(gmx_hw_opt_t *hw_opt,
+                                    int cutoff_scheme)
+{
+    gmx_omp_nthreads_read_env(&hw_opt->nthreads_omp);
+
+#ifndef GMX_THREAD_MPI
+    if (hw_opt->nthreads_tot > 0)
+    {
+        gmx_fatal(FARGS,"Setting the total number of threads is only supported with thread-MPI and Gromacs was compiled without thread-MPI");
+    }
+    if (hw_opt->nthreads_tmpi > 0)
+    {
+        gmx_fatal(FARGS,"Setting the number of thread-MPI threads is only supported with thread-MPI and Gromacs was compiled without thread-MPI");
+    }
+#endif
+
+    if (hw_opt->nthreads_tot > 0 && hw_opt->nthreads_omp_pme <= 0)
+    {
+        /* We have the same number of OpenMP threads for PP and PME processes,
+         * thus we can perform several consistency checks.
+         */
+        if (hw_opt->nthreads_tmpi > 0 &&
+            hw_opt->nthreads_omp > 0 &&
+            hw_opt->nthreads_tot != hw_opt->nthreads_tmpi*hw_opt->nthreads_omp)
+        {
+            gmx_fatal(FARGS,"The total number of threads requested (%d) does not match the thread-MPI threads (%d) times the OpenMP threads (%d) requested",
+                      hw_opt->nthreads_tot,hw_opt->nthreads_tmpi,hw_opt->nthreads_omp);
+        }
+
+        if (hw_opt->nthreads_tmpi > 0 &&
+            hw_opt->nthreads_tot % hw_opt->nthreads_tmpi != 0)
+        {
+            gmx_fatal(FARGS,"The total number of threads requested (%d) is not divisible by the number of thread-MPI threads requested (%d)",
+                      hw_opt->nthreads_tot,hw_opt->nthreads_tmpi);
+        }
+
+        if (hw_opt->nthreads_omp > 0 &&
+            hw_opt->nthreads_tot % hw_opt->nthreads_omp != 0)
+        {
+            gmx_fatal(FARGS,"The total number of threads requested (%d) is not divisible by the number of OpenMP threads requested (%d)",
+                      hw_opt->nthreads_tot,hw_opt->nthreads_omp);
+        }
+
+        if (hw_opt->nthreads_tmpi > 0 &&
+            hw_opt->nthreads_omp <= 0)
+        {
+            hw_opt->nthreads_omp = hw_opt->nthreads_tot/hw_opt->nthreads_tmpi;
+        }
+    }
+
+#ifndef GMX_OPENMP
+    if (hw_opt->nthreads_omp > 1)
+    {
+        gmx_fatal(FARGS,"OpenMP threads are requested, but Gromacs was compiled without OpenMP support");
+    }
+#endif
+
+    if (cutoff_scheme == ecutsGROUP)
+    {
+        /* We only have OpenMP support for PME only nodes */
+        if (hw_opt->nthreads_omp > 1)
+        {
+            gmx_fatal(FARGS,"OpenMP threads have been requested with cut-off scheme %s, but these are only supported with cut-off scheme %s",
+                      ecutscheme_names[cutoff_scheme],
+                      ecutscheme_names[ecutsVERLET]);
+        }
+        hw_opt->nthreads_omp = 1;
+    }
+
+    if (hw_opt->nthreads_omp_pme > 0 && hw_opt->nthreads_omp <= 0)
+    {
+        gmx_fatal(FARGS,"You need to specify -ntomp in addition to -ntomp_pme");
+    }
+
+    if (hw_opt->nthreads_tot == 1)
+    {
+        hw_opt->nthreads_tmpi = 1;
+
+        if (hw_opt->nthreads_omp > 1)
+        {
+            gmx_fatal(FARGS,"You requested %d OpenMP threads with %d total threads",
+                      hw_opt->nthreads_tmpi,hw_opt->nthreads_tot);
+        }
+        hw_opt->nthreads_omp = 1;
+    }
+
+    if (hw_opt->nthreads_omp_pme <= 0 && hw_opt->nthreads_omp > 0)
+    {
+        hw_opt->nthreads_omp_pme = hw_opt->nthreads_omp;
+    }
+
+    if (debug)
+    {
+        fprintf(debug,"hw_opt: nt %d ntmpi %d ntomp %d ntomp_pme %d gpu_id '%s'\n",
+                hw_opt->nthreads_tot,
+                hw_opt->nthreads_tmpi,
+                hw_opt->nthreads_omp,
+                hw_opt->nthreads_omp_pme,
+                hw_opt->gpu_id!=NULL ? hw_opt->gpu_id : "");
+                
+    }
+}
+
+
+/* Override the value in inputrec with value passed on the command line (if any) */
+static void override_nsteps_cmdline(FILE *fplog,
+                                    int nsteps_cmdline,
+                                    t_inputrec *ir,
+                                    const t_commrec *cr)
+{
+    assert(ir);
+    assert(cr);
+
+    /* override with anything else than the default -2 */
+    if (nsteps_cmdline > -2)
+    {
+        char stmp[STRLEN];
+
+        ir->nsteps = nsteps_cmdline;
+        if (EI_DYNAMICS(ir->eI))
+        {
+            sprintf(stmp, "Overriding nsteps with value passed on the command line: %d steps, %.3f ps",
+                    nsteps_cmdline, nsteps_cmdline*ir->delta_t);
+        }
+        else
+        {
+            sprintf(stmp, "Overriding nsteps with value passed on the command line: %d steps",
+                    nsteps_cmdline);
+        }
+
+        md_print_warn(cr, fplog, "%s\n", stmp);
+    }
+}
+
+/* Data structure set by SIMMASTER which needs to be passed to all nodes
+ * before the other nodes have read the tpx file and called gmx_detect_hardware.
+ */
+typedef struct {
+    int cutoff_scheme; /* The cutoff scheme from inputrec_t */
+    gmx_bool bUseGPU;       /* Use GPU or GPU emulation          */
+} master_inf_t;
+
+int mdrunner(gmx_hw_opt_t *hw_opt,
+             FILE *fplog,t_commrec *cr,int nfile,
+             const t_filenm fnm[], const output_env_t oenv, gmx_bool bVerbose,
+             gmx_bool bCompact, int nstglobalcomm,
+             ivec ddxyz,int dd_node_order,real rdd,real rconstr,
+             const char *dddlb_opt,real dlb_scale,
+             const char *ddcsx,const char *ddcsy,const char *ddcsz,
+             const char *nbpu_opt,
+             int nsteps_cmdline, int nstepout,int resetstep,
+             int nmultisim,int repl_ex_nst,int repl_ex_nex,
+             int repl_ex_seed, real pforce,real cpt_period,real max_hours,
+             const char *deviceOptions, unsigned long Flags)
+{
+    gmx_bool   bForceUseGPU,bTryUseGPU;
+    double     nodetime=0,realtime;
+    t_inputrec *inputrec;
+    t_state    *state=NULL;
+    matrix     box;
+    gmx_ddbox_t ddbox={0};
+    int        npme_major,npme_minor;
+    real       tmpr1,tmpr2;
+    t_nrnb     *nrnb;
+    gmx_mtop_t *mtop=NULL;
+    t_mdatoms  *mdatoms=NULL;
+    t_forcerec *fr=NULL;
+    t_fcdata   *fcd=NULL;
+    real       ewaldcoeff=0;
+    gmx_pme_t  *pmedata=NULL;
+    gmx_vsite_t *vsite=NULL;
+    gmx_constr_t constr;
+    int        i,m,nChargePerturbed=-1,status,nalloc;
+    char       *gro;
+    gmx_wallcycle_t wcycle;
+    gmx_bool       bReadRNG,bReadEkin;
+    int        list;
+    gmx_runtime_t runtime;
+    int        rc;
+    gmx_large_int_t reset_counters;
+    gmx_edsam_t ed=NULL;
+    t_commrec   *cr_old=cr; 
+    int         nthreads_pme=1;
+    int         nthreads_pp=1;
+    gmx_membed_t membed=NULL;
+    gmx_hw_info_t *hwinfo=NULL;
+    master_inf_t minf={-1,FALSE};
+
+    /* CAUTION: threads may be started later on in this function, so
+       cr doesn't reflect the final parallel state right now */
+    snew(inputrec,1);
+    snew(mtop,1);
+    
+    if (Flags & MD_APPENDFILES) 
+    {
+        fplog = NULL;
+    }
+
+    bForceUseGPU = (strncmp(nbpu_opt, "gpu", 3) == 0);
+    bTryUseGPU   = (strncmp(nbpu_opt, "auto", 4) == 0) || bForceUseGPU;
+
+    snew(state,1);
+    if (SIMMASTER(cr)) 
+    {
+        /* Read (nearly) all data required for the simulation */
+        read_tpx_state(ftp2fn(efTPX,nfile,fnm),inputrec,state,NULL,mtop);
+
+        if (inputrec->cutoff_scheme != ecutsVERLET &&
+            ((Flags & MD_TESTVERLET) || getenv("GMX_VERLET_SCHEME") != NULL))
+        {
+            convert_to_verlet_scheme(fplog,inputrec,mtop,det(state->box));
+        }
+
+        /* Detect hardware, gather information. With tMPI only thread 0 does it
+         * and after threads are started broadcasts hwinfo around. */
+        snew(hwinfo, 1);
+        gmx_detect_hardware(fplog, hwinfo, cr,
+                            bForceUseGPU, bTryUseGPU, hw_opt->gpu_id);
+
+        minf.cutoff_scheme = inputrec->cutoff_scheme;
+        minf.bUseGPU       = FALSE;
+
+        if (inputrec->cutoff_scheme == ecutsVERLET)
+        {
+            prepare_verlet_scheme(fplog,hwinfo,cr,hw_opt,nbpu_opt,
+                                  inputrec,mtop,state->box,
+                                  &minf.bUseGPU);
+        }
+        else if (hwinfo->bCanUseGPU)
+        {
+            md_print_warn(cr,fplog,
+                          "NOTE: GPU(s) found, but the current simulation can not use GPUs\n"
+                          "      To use a GPU, set the mdp option: cutoff-scheme = Verlet\n"
+                          "      (for quick performance testing you can use the -testverlet option)\n");
+
+            if (bForceUseGPU)
+            {
+                gmx_fatal(FARGS,"GPU requested, but can't be used without cutoff-scheme=Verlet");
+            }
+        }
+    }
+#ifndef GMX_THREAD_MPI
+    if (PAR(cr))
+    {
+        gmx_bcast_sim(sizeof(minf),&minf,cr);
+    }
+#endif
+    if (minf.bUseGPU && cr->npmenodes == -1)
+    {
+        /* Don't automatically use PME-only nodes with GPUs */
+        cr->npmenodes = 0;
+    }
+
+    /* Check for externally set OpenMP affinity and turn off internal
+     * pinning if any is found. We need to do this check early to tell
+     * thread-MPI whether it should do pinning when spawning threads.
+     */
+    gmx_omp_check_thread_affinity(fplog, cr, hw_opt);
+
+#ifdef GMX_THREAD_MPI
+    /* With thread-MPI inputrec is only set here on the master thread */
+    if (SIMMASTER(cr))
+#endif
+    {
+        check_and_update_hw_opt(hw_opt,minf.cutoff_scheme);
+
+#ifdef GMX_THREAD_MPI
+        /* Early check for externally set process affinity. Can't do over all
+         * MPI processes because hwinfo is not available everywhere, but with
+         * thread-MPI it's needed as pinning might get turned off which needs
+         * to be known before starting thread-MPI. */
+        check_cpu_affinity_set(fplog,
+                               NULL,
+                               hw_opt, hwinfo->nthreads_hw_avail, FALSE);
+#endif
+
+#ifdef GMX_THREAD_MPI
+        if (cr->npmenodes > 0 && hw_opt->nthreads_tmpi <= 0)
+        {
+            gmx_fatal(FARGS,"You need to explicitly specify the number of MPI threads (-ntmpi) when using separate PME nodes");
+        }
+#endif
+
+        if (hw_opt->nthreads_omp_pme != hw_opt->nthreads_omp &&
+            cr->npmenodes <= 0)
+        {
+            gmx_fatal(FARGS,"You need to explicitly specify the number of PME nodes (-npme) when using different number of OpenMP threads for PP and PME nodes");
+        }
+    }
+
+#ifdef GMX_THREAD_MPI
+    if (SIMMASTER(cr))
+    {
+        /* NOW the threads will be started: */
+        hw_opt->nthreads_tmpi = get_nthreads_mpi(hwinfo,
+                                                 hw_opt,
+                                                 inputrec, mtop,
+                                                 cr, fplog);
+        if (hw_opt->nthreads_tot > 0 && hw_opt->nthreads_omp <= 0)
+        {
+            hw_opt->nthreads_omp = hw_opt->nthreads_tot/hw_opt->nthreads_tmpi;
+        }
+
+        if (hw_opt->nthreads_tmpi > 1)
+        {
+            /* now start the threads. */
+            cr=mdrunner_start_threads(hw_opt, fplog, cr_old, nfile, fnm, 
+                                      oenv, bVerbose, bCompact, nstglobalcomm, 
+                                      ddxyz, dd_node_order, rdd, rconstr, 
+                                      dddlb_opt, dlb_scale, ddcsx, ddcsy, ddcsz,
+                                      nbpu_opt,
+                                      nsteps_cmdline, nstepout, resetstep, nmultisim, 
+                                      repl_ex_nst, repl_ex_nex, repl_ex_seed, pforce,
+                                      cpt_period, max_hours, deviceOptions, 
+                                      Flags);
+            /* the main thread continues here with a new cr. We don't deallocate
+               the old cr because other threads may still be reading it. */
+            if (cr == NULL)
+            {
+                gmx_comm("Failed to spawn threads");
+            }
+        }
+    }
+#endif
+    /* END OF CAUTION: cr is now reliable */
+
+    /* g_membed initialisation *
+     * Because we change the mtop, init_membed is called before the init_parallel *
+     * (in case we ever want to make it run in parallel) */
+    if (opt2bSet("-membed",nfile,fnm))
+    {
+        if (MASTER(cr))
+        {
+            fprintf(stderr,"Initializing membed");
+        }
+        membed = init_membed(fplog,nfile,fnm,mtop,inputrec,state,cr,&cpt_period);
+    }
+
+    if (PAR(cr))
+    {
+        /* now broadcast everything to the non-master nodes/threads: */
+        init_parallel(fplog, cr, inputrec, mtop);
+
+        /* This check needs to happen after get_nthreads_mpi() */
+        if (inputrec->cutoff_scheme == ecutsVERLET && (Flags & MD_PARTDEC))
+        {
+            gmx_fatal_collective(FARGS,cr,NULL,
+                                 "The Verlet cut-off scheme is not supported with particle decomposition.\n"
+                                 "You can achieve the same effect as particle decomposition by running in parallel using only OpenMP threads.");
+        }
+    }
+    if (fplog != NULL)
+    {
+        pr_inputrec(fplog,0,"Input Parameters",inputrec,FALSE);
+    }
+
+#if defined GMX_THREAD_MPI
+    /* With tMPI we detected on thread 0 and we'll just pass the hwinfo pointer
+     * to the other threads  -- slightly uncool, but works fine, just need to
+     * make sure that the data doesn't get freed twice. */
+    if (cr->nnodes > 1)
+    {
+        if (!SIMMASTER(cr))
+        {
+            snew(hwinfo, 1);
+        }
+        gmx_bcast(sizeof(&hwinfo), &hwinfo, cr);
+    }
+#else
+    if (PAR(cr) && !SIMMASTER(cr))
+    {
+        /* now we have inputrec on all nodes, can run the detection */
+        /* TODO: perhaps it's better to propagate within a node instead? */
+        snew(hwinfo, 1);
+        gmx_detect_hardware(fplog, hwinfo, cr,
+                                 bForceUseGPU, bTryUseGPU, hw_opt->gpu_id);
+    }
+
+    /* Now do the affinity check with MPI/no-MPI (done earlier with thread-MPI). */
+    check_cpu_affinity_set(fplog, cr,
+                           hw_opt, hwinfo->nthreads_hw_avail, FALSE);
+#endif
+
+    /* now make sure the state is initialized and propagated */
+    set_state_entries(state,inputrec,cr->nnodes);
+
+    /* remove when vv and rerun works correctly! */
+    if (PAR(cr) && EI_VV(inputrec->eI) && ((Flags & MD_RERUN) || (Flags & MD_RERUN_VSITE)))
+    {
+        gmx_fatal(FARGS,
+                  "Currently can't do velocity verlet with rerun in parallel.");
+    }
+
+    /* A parallel command line option consistency check that we can
+       only do after any threads have started. */
+    if (!PAR(cr) &&
+        (ddxyz[XX] > 1 || ddxyz[YY] > 1 || ddxyz[ZZ] > 1 || cr->npmenodes > 0))
+    {
+        gmx_fatal(FARGS,
+                  "The -dd or -npme option request a parallel simulation, "
+#ifndef GMX_MPI
+                  "but %s was compiled without threads or MPI enabled"
+#else
+#ifdef GMX_THREAD_MPI
+                  "but the number of threads (option -nt) is 1"
+#else
+                  "but %s was not started through mpirun/mpiexec or only one process was requested through mpirun/mpiexec"
+#endif
+#endif
+                  , ShortProgram()
+            );
+    }
+
+    if ((Flags & MD_RERUN) &&
+        (EI_ENERGY_MINIMIZATION(inputrec->eI) || eiNM == inputrec->eI))
+    {
+        gmx_fatal(FARGS, "The .mdp file specified an energy mininization or normal mode algorithm, and these are not compatible with mdrun -rerun");
+    }
+
+    if (can_use_allvsall(inputrec,mtop,TRUE,cr,fplog) && PAR(cr))
+    {
+        /* All-vs-all loops do not work with domain decomposition */
+        Flags |= MD_PARTDEC;
+    }
+
+    if (!EEL_PME(inputrec->coulombtype) || (Flags & MD_PARTDEC))
+    {
+        if (cr->npmenodes > 0)
+        {
+            if (!EEL_PME(inputrec->coulombtype))
+            {
+                gmx_fatal_collective(FARGS,cr,NULL,
+                                     "PME nodes are requested, but the system does not use PME electrostatics");
+            }
+            if (Flags & MD_PARTDEC)
+            {
+                gmx_fatal_collective(FARGS,cr,NULL,
+                                     "PME nodes are requested, but particle decomposition does not support separate PME nodes");
+            }
+        }
+
+        cr->npmenodes = 0;
+    }
+
+#ifdef GMX_FAHCORE
+    fcRegisterSteps(inputrec->nsteps,inputrec->init_step);
+#endif
+
+    /* NMR restraints must be initialized before load_checkpoint,
+     * since with time averaging the history is added to t_state.
+     * For proper consistency check we therefore need to extend
+     * t_state here.
+     * So the PME-only nodes (if present) will also initialize
+     * the distance restraints.
+     */
+    snew(fcd,1);
+
+    /* This needs to be called before read_checkpoint to extend the state */
+    init_disres(fplog,mtop,inputrec,cr,Flags & MD_PARTDEC,fcd,state);
+
+    if (gmx_mtop_ftype_count(mtop,F_ORIRES) > 0)
+    {
+        if (PAR(cr) && !(Flags & MD_PARTDEC))
+        {
+            gmx_fatal(FARGS,"Orientation restraints do not work (yet) with domain decomposition, use particle decomposition (mdrun option -pd)");
+        }
+        /* Orientation restraints */
+        if (MASTER(cr))
+        {
+            init_orires(fplog,mtop,state->x,inputrec,cr->ms,&(fcd->orires),
+                        state);
+        }
+    }
+
+    if (DEFORM(*inputrec))
+    {
+        /* Store the deform reference box before reading the checkpoint */
+        if (SIMMASTER(cr))
+        {
+            copy_mat(state->box,box);
+        }
+        if (PAR(cr))
+        {
+            gmx_bcast(sizeof(box),box,cr);
+        }
+        /* Because we do not have the update struct available yet
+         * in which the reference values should be stored,
+         * we store them temporarily in static variables.
+         * This should be thread safe, since they are only written once
+         * and with identical values.
+         */
+#ifdef GMX_THREAD_MPI
+        tMPI_Thread_mutex_lock(&deform_init_box_mutex);
+#endif
+        deform_init_init_step_tpx = inputrec->init_step;
+        copy_mat(box,deform_init_box_tpx);
+#ifdef GMX_THREAD_MPI
+        tMPI_Thread_mutex_unlock(&deform_init_box_mutex);
+#endif
+    }
+
+    if (opt2bSet("-cpi",nfile,fnm)) 
+    {
+        /* Check if checkpoint file exists before doing continuation.
+         * This way we can use identical input options for the first and subsequent runs...
+         */
+        if( gmx_fexist_master(opt2fn_master("-cpi",nfile,fnm,cr),cr) )
+        {
+            load_checkpoint(opt2fn_master("-cpi",nfile,fnm,cr),&fplog,
+                            cr,Flags & MD_PARTDEC,ddxyz,
+                            inputrec,state,&bReadRNG,&bReadEkin,
+                            (Flags & MD_APPENDFILES),
+                            (Flags & MD_APPENDFILESSET));
+            
+            if (bReadRNG)
+            {
+                Flags |= MD_READ_RNG;
+            }
+            if (bReadEkin)
+            {
+                Flags |= MD_READ_EKIN;
+            }
+        }
+    }
+
+    if (((MASTER(cr) || (Flags & MD_SEPPOT)) && (Flags & MD_APPENDFILES))
+#ifdef GMX_THREAD_MPI
+        /* With thread MPI only the master node/thread exists in mdrun.c,
+         * therefore non-master nodes need to open the "seppot" log file here.
+         */
+        || (!MASTER(cr) && (Flags & MD_SEPPOT))
+#endif
+        )
+    {
+        gmx_log_open(ftp2fn(efLOG,nfile,fnm),cr,!(Flags & MD_SEPPOT),
+                             Flags,&fplog);
+    }
+
+    /* override nsteps with value from cmdline */
+    override_nsteps_cmdline(fplog, nsteps_cmdline, inputrec, cr);
+
+    if (SIMMASTER(cr)) 
+    {
+        copy_mat(state->box,box);
+    }
+
+    if (PAR(cr)) 
+    {
+        gmx_bcast(sizeof(box),box,cr);
+    }
+
+    /* Essential dynamics */
+    if (opt2bSet("-ei",nfile,fnm))
+    {
+        /* Open input and output files, allocate space for ED data structure */
+        ed = ed_open(nfile,fnm,Flags,cr);
+    }
+
+    if (PAR(cr) && !((Flags & MD_PARTDEC) ||
+                     EI_TPI(inputrec->eI) ||
+                     inputrec->eI == eiNM))
+    {
+        cr->dd = init_domain_decomposition(fplog,cr,Flags,ddxyz,rdd,rconstr,
+                                           dddlb_opt,dlb_scale,
+                                           ddcsx,ddcsy,ddcsz,
+                                           mtop,inputrec,
+                                           box,state->x,
+                                           &ddbox,&npme_major,&npme_minor);
+
+        make_dd_communicators(fplog,cr,dd_node_order);
+
+        /* Set overallocation to avoid frequent reallocation of arrays */
+        set_over_alloc_dd(TRUE);
+    }
+    else
+    {
+        /* PME, if used, is done on all nodes with 1D decomposition */
+        cr->npmenodes = 0;
+        cr->duty = (DUTY_PP | DUTY_PME);
+        npme_major = 1;
+        npme_minor = 1;
+        if (!EI_TPI(inputrec->eI))
+        {
+            npme_major = cr->nnodes;
+        }
+        
+        if (inputrec->ePBC == epbcSCREW)
+        {
+            gmx_fatal(FARGS,
+                      "pbc=%s is only implemented with domain decomposition",
+                      epbc_names[inputrec->ePBC]);
+        }
+    }
+
+    if (PAR(cr))
+    {
+        /* After possible communicator splitting in make_dd_communicators.
+         * we can set up the intra/inter node communication.
+         */
+        gmx_setup_nodecomm(fplog,cr);
+    }
+
+    /* Initialize per-physical-node MPI process/thread ID and counters. */
+    gmx_init_intranode_counters(cr);
+
+#ifdef GMX_MPI
+    md_print_info(cr,fplog,"Using %d MPI %s\n",
+                  cr->nnodes,
+#ifdef GMX_THREAD_MPI
+                  cr->nnodes==1 ? "thread" : "threads"
+#else
+                  cr->nnodes==1 ? "process" : "processes"
+#endif
+                  );
+    fflush(stderr);
+#endif
+
+    gmx_omp_nthreads_init(fplog, cr,
+                          hwinfo->nthreads_hw_avail,
+                          hw_opt->nthreads_omp,
+                          hw_opt->nthreads_omp_pme,
+                          (cr->duty & DUTY_PP) == 0,
+                          inputrec->cutoff_scheme == ecutsVERLET);
+
+    gmx_check_hw_runconf_consistency(fplog, hwinfo, cr, hw_opt->nthreads_tmpi, minf.bUseGPU);
+
+    /* getting number of PP/PME threads
+       PME: env variable should be read only on one node to make sure it is 
+       identical everywhere;
+     */
+    /* TODO nthreads_pp is only used for pinning threads.
+     * This is a temporary solution until we have a hw topology library.
+     */
+    nthreads_pp  = gmx_omp_nthreads_get(emntNonbonded);
+    nthreads_pme = gmx_omp_nthreads_get(emntPME);
+
+    wcycle = wallcycle_init(fplog,resetstep,cr,nthreads_pp,nthreads_pme);
+
+    if (PAR(cr))
+    {
+        /* Master synchronizes its value of reset_counters with all nodes 
+         * including PME only nodes */
+        reset_counters = wcycle_get_reset_counters(wcycle);
+        gmx_bcast_sim(sizeof(reset_counters),&reset_counters,cr);
+        wcycle_set_reset_counters(wcycle, reset_counters);
+    }
+
+    snew(nrnb,1);
+    if (cr->duty & DUTY_PP)
+    {
+        /* For domain decomposition we allocate dynamically
+         * in dd_partition_system.
+         */
+        if (DOMAINDECOMP(cr))
+        {
+            bcast_state_setup(cr,state);
+        }
+        else
+        {
+            if (PAR(cr))
+            {
+                bcast_state(cr,state,TRUE);
+            }
+        }
+
+        /* Initiate forcerecord */
+        fr = mk_forcerec();
+        fr->hwinfo = hwinfo;
+        init_forcerec(fplog,oenv,fr,fcd,inputrec,mtop,cr,box,FALSE,
+                      opt2fn("-table",nfile,fnm),
+                      opt2fn("-tabletf",nfile,fnm),
+                      opt2fn("-tablep",nfile,fnm),
+                      opt2fn("-tableb",nfile,fnm),
+                      nbpu_opt,
+                      FALSE,pforce);
+
+        /* version for PCA_NOT_READ_NODE (see md.c) */
+        /*init_forcerec(fplog,fr,fcd,inputrec,mtop,cr,box,FALSE,
+          "nofile","nofile","nofile","nofile",FALSE,pforce);
+          */        
+        fr->bSepDVDL = ((Flags & MD_SEPPOT) == MD_SEPPOT);
+
+        /* Initialize QM-MM */
+        if(fr->bQMMM)
+        {
+            init_QMMMrec(cr,box,mtop,inputrec,fr);
+        }
+
+        /* Initialize the mdatoms structure.
+         * mdatoms is not filled with atom data,
+         * as this can not be done now with domain decomposition.
+         */
+        mdatoms = init_mdatoms(fplog,mtop,inputrec->efep!=efepNO);
+
+        /* Initialize the virtual site communication */
+        vsite = init_vsite(mtop,cr,FALSE);
+
+        calc_shifts(box,fr->shift_vec);
+
+        /* With periodic molecules the charge groups should be whole at start up
+         * and the virtual sites should not be far from their proper positions.
+         */
+        if (!inputrec->bContinuation && MASTER(cr) &&
+            !(inputrec->ePBC != epbcNONE && inputrec->bPeriodicMols))
+        {
+            /* Make molecules whole at start of run */
+            if (fr->ePBC != epbcNONE)
+            {
+                do_pbc_first_mtop(fplog,inputrec->ePBC,box,mtop,state->x);
+            }
+            if (vsite)
+            {
+                /* Correct initial vsite positions are required
+                 * for the initial distribution in the domain decomposition
+                 * and for the initial shell prediction.
+                 */
+                construct_vsites_mtop(fplog,vsite,mtop,state->x);
+            }
+        }
+
+        if (EEL_PME(fr->eeltype))
+        {
+            ewaldcoeff = fr->ewaldcoeff;
+            pmedata = &fr->pmedata;
+        }
+        else
+        {
+            pmedata = NULL;
+        }
+    }
+    else
+    {
+        /* This is a PME only node */
+
+        /* We don't need the state */
+        done_state(state);
+
+        ewaldcoeff = calc_ewaldcoeff(inputrec->rcoulomb, inputrec->ewald_rtol);
+        snew(pmedata,1);
+    }
+
+    /* Before setting affinity, check whether the affinity has changed
+     * - which indicates that probably the OpenMP library has changed it since
+     * we first checked). */
+    check_cpu_affinity_set(fplog, cr, hw_opt, hwinfo->nthreads_hw_avail, TRUE);
+
+    /* Set the CPU affinity */
+    set_cpu_affinity(fplog,cr,hw_opt,nthreads_pme,hwinfo,inputrec);
+
+    /* Initiate PME if necessary,
+     * either on all nodes or on dedicated PME nodes only. */
+    if (EEL_PME(inputrec->coulombtype))
+    {
+        if (mdatoms)
+        {
+            nChargePerturbed = mdatoms->nChargePerturbed;
+        }
+        if (cr->npmenodes > 0)
+        {
+            /* The PME only nodes need to know nChargePerturbed */
+            gmx_bcast_sim(sizeof(nChargePerturbed),&nChargePerturbed,cr);
+        }
+
+        if (cr->duty & DUTY_PME)
+        {
+            status = gmx_pme_init(pmedata,cr,npme_major,npme_minor,inputrec,
+                                  mtop ? mtop->natoms : 0,nChargePerturbed,
+                                  (Flags & MD_REPRODUCIBLE),nthreads_pme);
+            if (status != 0) 
+            {
+                gmx_fatal(FARGS,"Error %d initializing PME",status);
+            }
+        }
+    }
+
+
+    if (integrator[inputrec->eI].func == do_md
+        ||
+        integrator[inputrec->eI].func == do_md_openmm
+        )
+    {
+        /* Turn on signal handling on all nodes */
+        /*
+         * (A user signal from the PME nodes (if any)
+         * is communicated to the PP nodes.
+         */
+        signal_handler_install();
+    }
+
+    if (cr->duty & DUTY_PP)
+    {
+        if (inputrec->ePull != epullNO)
+        {
+            /* Initialize pull code */
+            init_pull(fplog,inputrec,nfile,fnm,mtop,cr,oenv, inputrec->fepvals->init_lambda,
+                      EI_DYNAMICS(inputrec->eI) && MASTER(cr),Flags);
+        }
+        
+        if (inputrec->bRot)
+        {
+           /* Initialize enforced rotation code */
+           init_rot(fplog,inputrec,nfile,fnm,cr,state->x,box,mtop,oenv,
+                    bVerbose,Flags);
+        }
+
+        constr = init_constraints(fplog,mtop,inputrec,ed,state,cr);
+
+        if (DOMAINDECOMP(cr))
+        {
+            dd_init_bondeds(fplog,cr->dd,mtop,vsite,constr,inputrec,
+                            Flags & MD_DDBONDCHECK,fr->cginfo_mb);
+
+            set_dd_parameters(fplog,cr->dd,dlb_scale,inputrec,fr,&ddbox);
+
+            setup_dd_grid(fplog,cr->dd);
+        }
+
+        /* Now do whatever the user wants us to do (how flexible...) */
+        integrator[inputrec->eI].func(fplog,cr,nfile,fnm,
+                                      oenv,bVerbose,bCompact,
+                                      nstglobalcomm,
+                                      vsite,constr,
+                                      nstepout,inputrec,mtop,
+                                      fcd,state,
+                                      mdatoms,nrnb,wcycle,ed,fr,
+                                      repl_ex_nst,repl_ex_nex,repl_ex_seed,
+                                      membed,
+                                      cpt_period,max_hours,
+                                      deviceOptions,
+                                      Flags,
+                                      &runtime);
+
+        if (inputrec->ePull != epullNO)
+        {
+            finish_pull(fplog,inputrec->pull);
+        }
+        
+        if (inputrec->bRot)
+        {
+            finish_rot(fplog,inputrec->rot);
+        }
+
+    } 
+    else 
+    {
+        /* do PME only */
+        gmx_pmeonly(*pmedata,cr,nrnb,wcycle,ewaldcoeff,FALSE,inputrec);
+    }
+
+    if (EI_DYNAMICS(inputrec->eI) || EI_TPI(inputrec->eI))
+    {
+        /* Some timing stats */  
+        if (SIMMASTER(cr))
+        {
+            if (runtime.proc == 0)
+            {
+                runtime.proc = runtime.real;
+            }
+        }
+        else
+        {
+            runtime.real = 0;
+        }
+    }
+
+    wallcycle_stop(wcycle,ewcRUN);
+
+    /* Finish up, write some stuff
+     * if rerunMD, don't write last frame again 
+     */
+    finish_run(fplog,cr,ftp2fn(efSTO,nfile,fnm),
+               inputrec,nrnb,wcycle,&runtime,
+               fr != NULL && fr->nbv != NULL && fr->nbv->bUseGPU ?
+                 nbnxn_cuda_get_timings(fr->nbv->cu_nbv) : NULL,
+               nthreads_pp, 
+               EI_DYNAMICS(inputrec->eI) && !MULTISIM(cr));
+
+    if ((cr->duty & DUTY_PP) && fr->nbv != NULL && fr->nbv->bUseGPU)
+    {
+        char gpu_err_str[STRLEN];
+
+        /* free GPU memory and uninitialize GPU (by destroying the context) */
+        nbnxn_cuda_free(fplog, fr->nbv->cu_nbv);
+
+        if (!free_gpu(gpu_err_str))
+        {
+            gmx_warning("On node %d failed to free GPU #%d: %s",
+                        cr->nodeid, get_current_gpu_device_id(), gpu_err_str);
+        }
+    }
+
+    if (opt2bSet("-membed",nfile,fnm))
+    {
+        sfree(membed);
+    }
+
+#ifdef GMX_THREAD_MPI
+    if (PAR(cr) && SIMMASTER(cr))
+#endif
+    {
+        gmx_hardware_info_free(hwinfo);
+    }
+
+    /* Does what it says */  
+    print_date_and_time(fplog,cr->nodeid,"Finished mdrun",&runtime);
+
+    /* Close logfile already here if we were appending to it */
+    if (MASTER(cr) && (Flags & MD_APPENDFILES))
+    {
+        gmx_log_close(fplog);
+    }  
+
+    rc=(int)gmx_get_stop_condition();
+
+#ifdef GMX_THREAD_MPI
+    /* we need to join all threads. The sub-threads join when they
+       exit this function, but the master thread needs to be told to 
+       wait for that. */
+    if (PAR(cr) && MASTER(cr))
+    {
+        tMPI_Finalize();
+    }
+#endif
+
+    return rc;
+}
index 425cc60d89b7b24c083de6c8dded03726c38eeee..773f8d587ce2d9e5a3f6fc19983ecf133cc57f8d 100644 (file)
@@ -87,7 +87,7 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libgromacs.pc
         COMPONENT development)
 
 if (INSTALL_CUDART_LIB) #can be set manual by user
-    if (GMX_OPENMM OR GMX_GPU)
+    if (GMX_GPU)
         foreach(CUDA_LIB ${CUDA_LIBRARIES})
             string(REGEX MATCH "cudart" IS_CUDART ${CUDA_LIB})
             if(IS_CUDART) #libcuda should not be installed
@@ -98,6 +98,6 @@ if (INSTALL_CUDART_LIB) #can be set manual by user
             endif()
         endforeach()
     else()
-        message(WARNING "INSTALL_CUDART_LIB only makes sense with GMX_OPENMM or GMX_GPU")
+        message(WARNING "INSTALL_CUDART_LIB only makes sense with GMX_GPU")
     endif()
 endif ()
index f426643ced340a9dd5ace20a83735a308f6394db..405fa477c9497e9a70859ccfa4255481d7672b23 100644 (file)
@@ -44,18 +44,6 @@ struct gmx_invsqrtdata
   unsigned int    fracttab[4096]; /*!< Mantissa lookup table    */
 };
 
-#ifndef F77_FUNC
-/*! \brief Macro for Fortran name-mangling
- *
- * Use Fortran name mangling from autoconf macros if defined, 
- * or lowercase+underscore by default. Since there is no easy way to convert
- * between lower and upper case in macros, you should call fortran routines
- * as F77_FUNC(routine,ROUTINE)(param1,param2,...)
- */
-#define F77_FUNC(name,NAME) name ## _
-#endif
-
-
 
 struct gmx_invsqrtdata 
 F77_FUNC(gmxinvsqrtdata,GMXINVSQRTDATA) = 
index dc7bd69ca1a925af381b347adce9055893d488e8..3534d996ba150d454aaf46289176f0a3efee2cc5 100644 (file)
@@ -55,7 +55,7 @@
 
 void init_disres(FILE *fplog,const gmx_mtop_t *mtop,
                  t_inputrec *ir,const t_commrec *cr,gmx_bool bPartDecomp,
-                 t_fcdata *fcd,t_state *state)
+                 t_fcdata *fcd,t_state *state, gmx_bool bIsREMD)
 {
     int          fa,nmol,i,npair,np;
     t_iparams    *ip;
@@ -181,7 +181,7 @@ void init_disres(FILE *fplog,const gmx_mtop_t *mtop,
     dd->Rtav_6 = &(dd->Rt_6[dd->nres]);
 
     ptr = getenv("GMX_DISRE_ENSEMBLE_SIZE");
-    if (cr && cr->ms != NULL && ptr != NULL)
+    if (cr && cr->ms != NULL && ptr != NULL && !bIsREMD)
     {
 #ifdef GMX_MPI
         dd->nsystems = 0;
@@ -190,8 +190,17 @@ void init_disres(FILE *fplog,const gmx_mtop_t *mtop,
         {
             fprintf(fplog,"Found GMX_DISRE_ENSEMBLE_SIZE set to %d systems per ensemble\n",dd->nsystems);
         }
-        check_multi_int(fplog,cr->ms,dd->nsystems,
-                        "the number of systems per ensemble");
+        /* This check is only valid on MASTER(cr), so probably
+         * ensemble-averaged distance restraints are broken on more
+         * than one processor per simulation system. */
+        if (MASTER(cr))
+        {
+            check_multi_int(fplog,cr->ms,dd->nsystems,
+                            "the number of systems per ensemble",
+                            FALSE);
+        }
+        gmx_bcast_sim(sizeof(int), &dd->nsystems, cr);
+
         /* We use to allow any value of nsystems which was a divisor
          * of ms->nsim. But this required an extra communicator which
          * was stored in t_fcdata. This pulled in mpi.h in nearly all C files.
@@ -200,7 +209,6 @@ void init_disres(FILE *fplog,const gmx_mtop_t *mtop,
         {
             gmx_fatal(FARGS,"GMX_DISRE_ENSEMBLE_SIZE (%d) is not equal to 1 or the number of systems (option -multi) %d",dd->nsystems,cr->ms->nsim);
         }
-
         if (fplog)
         {
             fprintf(fplog,"Our ensemble consists of systems:");
@@ -225,10 +233,17 @@ void init_disres(FILE *fplog,const gmx_mtop_t *mtop,
         if (fplog) {
             fprintf(fplog,"There are %d distance restraints involving %d atom pairs\n",dd->nres,dd->npair);
         }
-        if (cr && cr->ms)
+        /* Have to avoid g_disre de-referencing cr blindly, mdrun not
+         * doing consistency checks for ensemble-averaged distance
+         * restraints when that's not happening, and only doing those
+         * checks from appropriate processes (since check_multi_int is
+         * too broken to check whether the communication will
+         * succeed...) */
+        if (cr && cr->ms && dd->nsystems > 1 && MASTER(cr))
         {
             check_multi_int(fplog,cr->ms,fcd->disres.nres,
-                            "the number of distance restraints");
+                            "the number of distance restraints",
+                            FALSE);
         }
         please_cite(fplog,"Tropp80a");
         please_cite(fplog,"Torda89a");
index e7c2d65e1e198742921394b90671956468d54023..150027514c99ebdb8529272c2c6d65f647b7b9e3 100644 (file)
@@ -318,7 +318,7 @@ void gmx_check_hw_runconf_consistency(FILE *fplog, gmx_hw_info_t *hwinfo,
                     md_print_warn(cr,fplog,
                                   "NOTE: potentially sub-optimal launch configuration, %s started with less\n"
                                   "      PP %s%s%s than GPU%s available.\n"
-                                  "      Each PP %s can only use one GPU, so only %d GPU%s%s will be used.",
+                                  "      Each PP %s can use only one GPU, %d GPU%s%s will be used.\n",
                                   ShortProgram(),
                                   th_or_proc, th_or_proc_plural, pernode, gpu_plural,
                                   th_or_proc, npppn, gpu_plural, pernode);
@@ -356,12 +356,13 @@ void gmx_check_hw_runconf_consistency(FILE *fplog, gmx_hw_info_t *hwinfo,
             }
         }
 
+        hwinfo->gpu_info.bDevShare = FALSE;
         if (hwinfo->gpu_info.bUserSet && (cr->rank_pp_intranode == 0))
         {
             int i, j, same_count;
             gmx_bool bSomeSame, bAllDifferent;
 
-            same_count = 0;
+            same_count = 0; /* number of GPUs shared among ranks */
             bSomeSame = FALSE;
             bAllDifferent = TRUE;
 
@@ -375,6 +376,9 @@ void gmx_check_hw_runconf_consistency(FILE *fplog, gmx_hw_info_t *hwinfo,
                 }
             }
 
+            /* store the number of shared/oversubscribed GPUs */
+            hwinfo->gpu_info.bDevShare = bSomeSame;
+
             if (btMPI && !bAllDifferent)
             {
                 gmx_fatal(FARGS,
@@ -386,8 +390,8 @@ void gmx_check_hw_runconf_consistency(FILE *fplog, gmx_hw_info_t *hwinfo,
             {
                 md_print_warn(cr,fplog,
                               "NOTE: Potentially sub-optimal launch configuration: you assigned %s to\n"
-                              "      multiple %s%s; this should be avoided as it generally\n"
-                              "      causes performance loss.",
+                              "      multiple %s%s; this should be avoided as it can cause\n"
+                              "      performance loss.\n",
                               same_count > 1 ? "GPUs" : "a GPU", th_or_proc, btMPI ? "s" : "es");
             }
         }
index 673025b7697dad412210da03097c2329f1b1cb78..b5a5a7ace2967e619487a51dd288dd7a770c1857 100644 (file)
@@ -186,9 +186,12 @@ static int pick_module_nthreads(FILE *fplog, int m,
     return modth.nth[m] = nth;
 }
 
-void gmx_omp_nthreads_read_env(int *nthreads_omp)
+void gmx_omp_nthreads_read_env(int *nthreads_omp,
+                               gmx_bool bIsSimMaster)
 {
     char *env;
+    gmx_bool bCommandLineSetNthreadsOMP = *nthreads_omp > 0;
+    char buffer[STRLEN];
 
     assert(nthreads_omp);
 
@@ -202,17 +205,33 @@ void gmx_omp_nthreads_read_env(int *nthreads_omp)
             gmx_fatal(FARGS,"OMP_NUM_THREADS is invalid: '%s'",env);
         }
 
-        if (*nthreads_omp > 0 && nt_omp != *nthreads_omp)
+        if (bCommandLineSetNthreadsOMP && nt_omp != *nthreads_omp)
         {
-            gmx_fatal(FARGS,"OMP_NUM_THREADS (%d) and the number of threads requested on the command line (%d) have different values",nt_omp,*nthreads_omp);
+            gmx_fatal(FARGS,"Environment variable OMP_NUM_THREADS (%d) and the number of threads requested on the command line (%d) have different values. Either omit one, or set them both to the same value.",nt_omp,*nthreads_omp);
         }
 
-        /* Setting the number of OpenMP threads.
-         * NOTE: with tMPI this function is only called on the master node,
-         * but with MPI on all nodes which means lots of messages on stderr.
-         */
-        fprintf(stderr,"Getting the number of OpenMP threads from OMP_NUM_THREADS: %d\n",nt_omp);
+        /* Setting the number of OpenMP threads. */
         *nthreads_omp = nt_omp;
+
+        /* Output the results */
+        sprintf(buffer,
+                "The number of OpenMP threads was set by environment variable OMP_NUM_THREADS to %d%s\n",
+                nt_omp,
+                bCommandLineSetNthreadsOMP ? " (and the command-line setting agreed with that)" : "");
+        if (bIsSimMaster)
+        {
+            /* This prints once per simulation for multi-simulations,
+             * which might help diagnose issues with inhomogenous
+             * cluster setups. */
+            fputs(buffer, stderr);
+        }
+        if (debug)
+        {
+            /* This prints once per process for real MPI (i.e. once
+             * per debug file), and once per simulation for thread MPI
+             * (because of logic in the calling function). */
+            fputs(buffer, debug);
+        }
     }
 }
 
index c29b74dff18465f448d0084bae4d465e5745645d..8ebb232db7e4a83700ca162bd96a84b42b46e307 100644 (file)
@@ -9,7 +9,7 @@
  * 
  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2010, The GROMACS development team,
+ * Copyright (c) 2001-2010,2012 The GROMACS development team,
  * check out http://www.gromacs.org for more information.
 
  * This program is free software; you can redistribute it and/or
@@ -57,9 +57,6 @@
 #define TIMED_TESTS     MOD_20_32BIT | LOGIC_4_ITER_SHMEM | RANDOM_BLOCKS /*!< Bit flag with type of tests to
                                                                             run in time constrained memtest. */
 
-/*! Number of supported GPUs */
-#define NB_GPUS (sizeof(SupportedGPUs)/sizeof(SupportedGPUs[0]))
-
 static int cuda_max_device_count = 32; /*! Max number of devices supported by CUDA (for consistency checking).
                                            In reality it 16 with CUDA <=v5.0, but let's stay on the safe side. */
 
@@ -84,55 +81,6 @@ enum memtest_G80_test_types {
     LOGIC_4_ITER_SHMEM =        0x1000
 };
 
-// TODO put this list into an external file and include it so that the list is easily accessible
-/*! List of supported GPUs. */
-static const char * const SupportedGPUs[] = {
-    /* GT400 */
-    "Geforce GTX 480",
-    "Geforce GTX 470",
-    "Geforce GTX 465",
-    "Geforce GTX 460",
-
-    "Tesla C2070",
-    "Tesla C2050",
-    "Tesla S2070",
-    "Tesla S2050",
-    "Tesla M2070",
-    "Tesla M2050",
-
-    "Quadro 5000",
-    "Quadro 6000",
-
-    /* GT200 */
-    "Geforce GTX 295",
-    "Geforce GTX 285",
-    "Geforce GTX 280",
-    "Geforce GTX 275",
-    "Geforce GTX 260",
-    "GeForce GTS 250",
-    "GeForce GTS 150",
-
-    "GeForce GTX 285M",
-    "GeForce GTX 280M",
-
-    "Tesla S1070",
-    "Tesla C1060",
-    "Tesla M1060",
-
-    "Quadro FX 5800",
-    "Quadro FX 4800",
-    "Quadro CX",
-    "Quadro Plex 2200 D2",
-    "Quadro Plex 2200 S4",
-
-    /* G90 */
-    "GeForce 9800 G", /* GX2, GTX, GTX+, GT */
-    "GeForce 9800M GTX",
-
-    "Quadro FX 4700",
-    "Quadro Plex 2100 D4"
-};
-
 
 /*! 
   * \brief Runs GPU sanity checks.
@@ -240,48 +188,6 @@ static int do_sanity_checks(int dev_id, cudaDeviceProp *dev_prop)
 }
 
 
-/*! 
- * \brief Checks whether the GPU with the given name is supported in Gromacs-OpenMM.
- * 
- * \param[in] gpu_name  the name of the CUDA device
- * \returns             TRUE if the device is supported, otherwise FALSE
- */
-static bool is_gmx_openmm_supported_gpu_name(char *gpuName)
-{
-    size_t i;
-    for (i = 0; i < NB_GPUS; i++)
-    {
-        trim(gpuName);
-        if (gmx_strncasecmp(gpuName, SupportedGPUs[i], strlen(SupportedGPUs[i])) == 0)
-            return 1;
-    }
-    return 0;
-}
-
-/*! \brief Checks whether the GPU with the given device id is supported in Gromacs-OpenMM.
- *
- * \param[in] dev_id    the device id of the GPU or -1 if the device has already been selected
- * \param[out] gpu_name Set to contain the name of the CUDA device, if NULL passed, no device name is set. 
- * \returns             TRUE if the device is supported, otherwise FALSE
- * 
- */
-gmx_bool is_gmx_openmm_supported_gpu(int dev_id, char *gpu_name)
-{
-    cudaDeviceProp dev_prop;
-
-    if (debug) fprintf(debug, "Checking compatibility with device #%d, %s\n", dev_id, gpu_name);
-
-    if (do_sanity_checks(dev_id, &dev_prop) != 0)
-        return -1;
-
-    if (gpu_name != NULL)
-    { 
-        strcpy(gpu_name, dev_prop.name);
-    }
-    return is_gmx_openmm_supported_gpu_name(dev_prop.name);
-}
-
-
 /*!
  * \brief Runs a set of memory tests specified by the given bit-flags.
  * Tries to allocate and do the test on \p megs Mb memory or
index 9a2be229fe2fb115feb62764182520abad476773..b76cac81fea6813e6369144d9135afff72424ca3 100644 (file)
@@ -76,422 +76,6 @@ const char *xdr_datatype_names[] =
 };
 
 
-#ifdef GMX_FORTRAN
-
-/* NOTE: DO NOT USE THESE ANYWHERE IN GROMACS ITSELF. 
-   These are necessary for the backward-compatile io routines for 3d party
-   tools */
-#define MAXID 256
-static FILE *xdrfiles[MAXID];
-static XDR *xdridptr[MAXID];
-static char xdrmodes[MAXID];
-static unsigned int cnt;
-#ifdef GMX_THREAD_MPI
-/* we need this because of the global variables above for FORTRAN binding. 
-   The I/O operations are going to be slow. */
-static tMPI_Thread_mutex_t xdr_fortran_mutex=TMPI_THREAD_MUTEX_INITIALIZER;
-#endif
-
-static void xdr_fortran_lock(void)
-{
-#ifdef GMX_THREAD_MPI
-    tMPI_Thread_mutex_lock(&xdr_fortran_mutex);
-#endif
-}
-static void xdr_fortran_unlock(void)
-{
-#ifdef GMX_THREAD_MPI
-    tMPI_Thread_mutex_unlock(&xdr_fortran_mutex);
-#endif
-}
-
-
-
-/* the open&close prototypes */
-static int xdropen(XDR *xdrs, const char *filename, const char *type);
-static int xdrclose(XDR *xdrs);
-
-typedef void (* F77_FUNC(xdrfproc,XDRFPROC))(int *, void *, int *);
-
-int ftocstr(char *ds, int dl, char *ss, int sl)
-    /* dst, src ptrs */
-    /* dst max len */
-    /* src len */
-{
-    char *p;
-
-    p = ss + sl;
-    while ( --p >= ss && *p == ' ' );
-    sl = p - ss + 1;
-    dl--;
-    ds[0] = 0;
-    if (sl > dl)
-      return 1;
-    while (sl--)
-      (*ds++ = *ss++);
-    *ds = '\0';
-    return 0;
-}
-
-
-int ctofstr(char *ds, int dl, char *ss)
-     /* dest space */
-     /* max dest length */
-     /* src string (0-term) */
-{
-    while (dl && *ss) {
-       *ds++ = *ss++;
-       dl--;
-    }
-    while (dl--)
-       *ds++ = ' ';
-    return 0;
-}
-
-void
-F77_FUNC(xdrfbool,XDRFBOOL)(int *xdrid, int *pb, int *ret) 
-{
-        xdr_fortran_lock();
-       *ret = xdr_bool(xdridptr[*xdrid], pb);
-       cnt += XDR_INT_SIZE;
-        xdr_fortran_unlock();
-}
-
-void
-F77_FUNC(xdrfchar,XDRFCHAR)(int *xdrid, char *cp, int *ret)
-{
-        xdr_fortran_lock();
-       *ret = xdr_char(xdridptr[*xdrid], cp);
-       cnt += sizeof(char);
-        xdr_fortran_unlock();
-}
-
-void
-F77_FUNC(xdrfdouble,XDRFDOUBLE)(int *xdrid, double *dp, int *ret)
-{
-        xdr_fortran_lock();
-       *ret = xdr_double(xdridptr[*xdrid], dp);
-       cnt += sizeof(double);
-        xdr_fortran_unlock();
-}
-
-void
-F77_FUNC(xdrffloat,XDRFFLOAT)(int *xdrid, float *fp, int *ret)
-{
-        xdr_fortran_lock();
-       *ret = xdr_float(xdridptr[*xdrid], fp);
-       cnt += sizeof(float);
-        xdr_fortran_unlock();
-}
-
-void
-F77_FUNC(xdrfint,XDRFINT)(int *xdrid, int *ip, int *ret)
-{
-        xdr_fortran_lock();
-       *ret = xdr_int(xdridptr[*xdrid], ip);
-       cnt += XDR_INT_SIZE;
-        xdr_fortran_unlock();
-}
-
-void
-F77_FUNC(xdrfshort,XDRFSHORT)(int *xdrid, short *sp, int *ret)
-{
-        xdr_fortran_lock();
-       *ret = xdr_short(xdridptr[*xdrid], sp);
-       cnt += sizeof(sp);
-        xdr_fortran_unlock();
-}
-
-void
-F77_FUNC(xdrfuchar,XDRFUCHAR)(int *xdrid, unsigned char *ucp, int *ret)
-{
-        xdr_fortran_lock();
-       *ret = xdr_u_char(xdridptr[*xdrid], (u_char *)ucp);
-       cnt += sizeof(char);
-        xdr_fortran_unlock();
-}
-
-
-void
-F77_FUNC(xdrfushort,XDRFUSHORT)(int *xdrid, unsigned short *usp, int *ret)
-{
-        xdr_fortran_lock();
-       *ret = xdr_u_short(xdridptr[*xdrid], (unsigned short *)usp);
-       cnt += sizeof(unsigned short);
-        xdr_fortran_unlock();
-}
-
-void 
-F77_FUNC(xdrf3dfcoord,XDRF3DFCOORD)(int *xdrid, float *fp, int *size, float *precision, int *ret)
-{
-        xdr_fortran_lock();
-       *ret = xdr3dfcoord(xdridptr[*xdrid], fp, size, precision);
-        xdr_fortran_unlock();
-}
-
-void
-F77_FUNC(xdrfstring,XDRFSTRING)(int *xdrid, char * sp_ptr,
-                               int *maxsize, int *ret, int sp_len)
-{
-       char *tsp;
-
-        xdr_fortran_lock();
-       tsp = (char*) malloc((size_t)(((sp_len) + 1) * sizeof(char)));
-       if (tsp == NULL) {
-           *ret = -1;
-           return;
-       }
-       if (ftocstr(tsp, *maxsize+1, sp_ptr, sp_len)) {
-           *ret = -1;
-           free(tsp);
-            xdr_fortran_unlock();
-           return;
-       }
-        *ret = xdr_string(xdridptr[*xdrid], (char **) &tsp, (unsigned int) *maxsize);
-       ctofstr( sp_ptr, sp_len , tsp);
-       cnt += *maxsize;
-       free(tsp);
-        xdr_fortran_unlock();
-}
-
-void
-F77_FUNC(xdrfwrapstring,XDRFWRAPSTRING)(int *xdrid, char *sp_ptr,
-                                       int *ret, int sp_len)
-{
-       char *tsp;
-       int maxsize;
-
-        xdr_fortran_lock();
-       maxsize = (sp_len) + 1;
-       tsp = (char*) malloc((size_t)(maxsize * sizeof(char)));
-       if (tsp == NULL) {
-           *ret = -1;
-           return;
-            xdr_fortran_unlock();
-       }
-       if (ftocstr(tsp, maxsize, sp_ptr, sp_len)) {
-           *ret = -1;
-           free(tsp);
-           return;
-            xdr_fortran_unlock();
-       }
-       *ret = xdr_string(xdridptr[*xdrid], (char **) &tsp, (u_int)maxsize);
-       ctofstr( sp_ptr, sp_len, tsp);
-       cnt += maxsize;
-       free(tsp);
-        xdr_fortran_unlock();
-}
-
-void
-F77_FUNC(xdrfopaque,XDRFOPAQUE)(int *xdrid, caddr_t *cp, int *ccnt, int *ret)
-{
-        xdr_fortran_lock();
-       *ret = xdr_opaque(xdridptr[*xdrid], (caddr_t)*cp, (u_int)*ccnt);
-       cnt += *ccnt;
-        xdr_fortran_unlock();
-}
-
-void
-F77_FUNC(xdrfsetpos,XDRFSETPOS)(int *xdrid, int *pos, int *ret)
-{
-        xdr_fortran_lock();
-       *ret = xdr_setpos(xdridptr[*xdrid], (u_int) *pos);
-        xdr_fortran_unlock();
-}
-
-
-void
-F77_FUNC(xdrf,XDRF)(int *xdrid, int *pos)
-{
-        xdr_fortran_lock();
-       *pos = xdr_getpos(xdridptr[*xdrid]);
-        xdr_fortran_unlock();
-}
-
-void
-F77_FUNC(xdrfvector,XDRFVECTOR)(int *xdrid, char *cp, int *size, F77_FUNC(xdrfproc,XDRFPROC) elproc, int *ret) 
-{
-       int lcnt;
-       cnt = 0;
-        xdr_fortran_lock();
-       for (lcnt = 0; lcnt < *size; lcnt++) {
-               elproc(xdrid, (cp+cnt) , ret);
-       }
-        xdr_fortran_unlock();
-}
-
-
-void
-F77_FUNC(xdrfclose,XDRFCLOSE)(int *xdrid, int *ret)
-{
-        xdr_fortran_lock();
-       *ret = xdrclose(xdridptr[*xdrid]);
-       cnt = 0;
-        xdr_fortran_unlock();
-}
-
-void
-F77_FUNC(xdrfopen,XDRFOPEN)(int *xdrid, char *fp_ptr, char *mode_ptr,
-                           int *ret, int fp_len, int mode_len)
-{
-       char fname[512];
-       char fmode[3];
-
-        xdr_fortran_lock();
-       if (ftocstr(fname, sizeof(fname), fp_ptr, fp_len)) {
-               *ret = 0;
-       }
-       if (ftocstr(fmode, sizeof(fmode), mode_ptr,
-                       mode_len)) {
-               *ret = 0;
-       }
-
-       *xdrid = xdropen(NULL, fname, fmode);
-       if (*xdrid == 0)
-               *ret = 0;
-       else 
-               *ret = 1;       
-        xdr_fortran_unlock();
-}
-
-/*__________________________________________________________________________
- |
- | xdropen - open xdr file
- |
- | This versions differs from xdrstdio_create, because I need to know
- | the state of the file (read or write)  and the file descriptor
- | so I can close the file (something xdr_destroy doesn't do).
- |
- | It assumes xdr_fortran_mutex is locked.
- |
- | NOTE: THIS FUNCTION IS NOW OBSOLETE AND ONLY PROVIDED FOR BACKWARD
- |       COMPATIBILITY OF 3D PARTY TOOLS. IT SHOULD NOT BE USED ANYWHERE 
- |       IN GROMACS ITSELF. 
-*/
-
-int xdropen(XDR *xdrs, const char *filename, const char *type) {
-    static int init_done = 0;
-    enum xdr_op lmode;
-    int xdrid;
-    char newtype[5];
-
-
-#ifdef GMX_THREAD_MPI
-    if (!tMPI_Thread_mutex_trylock( &xdr_fortran_mutex ))  
-    {
-        tMPI_Thread_mutex_unlock( &xdr_fortran_mutex );
-        gmx_incons("xdropen called without locked mutex. NEVER call this function.");
-    }
-#endif 
-
-    if (init_done == 0) {
-       for (xdrid = 1; xdrid < MAXID; xdrid++) {
-           xdridptr[xdrid] = NULL;
-       }
-       init_done = 1;
-    }
-    xdrid = 1;
-    while (xdrid < MAXID && xdridptr[xdrid] != NULL) {
-       xdrid++;
-    }
-    if (xdrid == MAXID) {
-       return 0;
-    }
-    if (*type == 'w' || *type == 'W')
-    {
-        xdrmodes[xdrid] = 'w';
-        strcpy(newtype, "wb+");
-        lmode = XDR_ENCODE;
-    }
-    else if (*type == 'a' || *type == 'A')
-    {
-        xdrmodes[xdrid] = 'a';
-        strcpy(newtype, "ab+");
-        lmode = XDR_ENCODE;
-    }
-    else if (gmx_strncasecmp(type, "r+", 2) == 0)
-    {
-        xdrmodes[xdrid] = 'a';
-        strcpy(newtype, "rb+");
-        lmode = XDR_ENCODE;
-    }
-    else
-    {
-        xdrmodes[xdrid] = 'r';
-        strcpy(newtype, "rb");
-        lmode = XDR_DECODE;
-    }
-    xdrfiles[xdrid] = fopen(filename, newtype);
-       
-    if (xdrfiles[xdrid] == NULL) {
-       xdrs = NULL;
-       return 0;
-    }
-    
-    /* next test isn't useful in the case of C language
-     * but is used for the Fortran interface
-     * (C users are expected to pass the address of an already allocated
-     * XDR staructure)
-     */
-    if (xdrs == NULL) {
-       xdridptr[xdrid] = (XDR *) malloc((size_t)sizeof(XDR));
-       xdrstdio_create(xdridptr[xdrid], xdrfiles[xdrid], lmode);
-    } else {
-       xdridptr[xdrid] = xdrs;
-       xdrstdio_create(xdrs, xdrfiles[xdrid], lmode);
-    }
-    return xdrid;
-}
-/*_________________________________________________________________________
- |
- | xdrclose - close a xdr file
- |
- | This will flush the xdr buffers, and destroy the xdr stream.
- | It also closes the associated file descriptor (this is *not*
- | done by xdr_destroy).
- |
- | It assumes xdr_fortran_mutex is locked.
- |
- | NOTE: THIS FUNCTION IS NOW OBSOLETE AND ONLY PROVIDED FOR BACKWARD
- |       COMPATIBILITY OF 3D PARTY TOOLS. IT SHOULD NOT BE USED ANYWHERE 
- |       IN GROMACS ITSELF. 
-*/
-int xdrclose(XDR *xdrs) {
-    int xdrid;
-    int rc = 0;
-
-#ifdef GMX_THREAD_MPI
-    if (!tMPI_Thread_mutex_trylock( &xdr_fortran_mutex ))  
-    {
-        tMPI_Thread_mutex_unlock( &xdr_fortran_mutex );
-        gmx_incons("xdropen called without locked mutex. NEVER call this function");
-    }
-#endif
-
-    if (xdrs == NULL) {
-       fprintf(stderr, "xdrclose: passed a NULL pointer\n");
-       exit(1);
-    }
-    for (xdrid = 1; xdrid < MAXID && rc==0; xdrid++) {
-       if (xdridptr[xdrid] == xdrs) {
-           
-           xdr_destroy(xdrs);
-           rc = fclose(xdrfiles[xdrid]);
-           xdridptr[xdrid] = NULL;
-           return !rc; /* xdr routines return 0 when ok */
-       }
-    } 
-    fprintf(stderr, "xdrclose: no such open xdr file\n");
-    exit(1);
-    
-    /* to make some compilers happy: */
-    return 0;    
-}
-
-#endif /* GMX_FORTRAN */
-
-
 /*___________________________________________________________________________
  |
  | what follows are the C routine to read/write compressed coordinates together
index 678b402faf018a6ffc228269e64515064a545fb9..baf41cdcd62bd8aaab54f006663fffcb5b6522d6 100644 (file)
@@ -119,12 +119,13 @@ static void par_fn(char *base,int ftp,const t_commrec *cr,
 }
 
 void check_multi_int(FILE *log,const gmx_multisim_t *ms,int val,
-                     const char *name)
+                     const char *name,
+                     gmx_bool bQuiet)
 {
   int  *ibuf,p;
   gmx_bool bCompatible;
 
-  if (NULL != log)
+  if (NULL != log && !bQuiet)
       fprintf(log,"Multi-checking %s ... ",name);
   
   if (ms == NULL)
@@ -141,7 +142,7 @@ void check_multi_int(FILE *log,const gmx_multisim_t *ms,int val,
   
   if (bCompatible) 
   {
-      if (NULL != log)
+      if (NULL != log && !bQuiet)
           fprintf(log,"OK\n");
   }
   else 
@@ -159,13 +160,14 @@ void check_multi_int(FILE *log,const gmx_multisim_t *ms,int val,
 }
 
 void check_multi_large_int(FILE *log,const gmx_multisim_t *ms,
-                           gmx_large_int_t val, const char *name)
+                           gmx_large_int_t val, const char *name,
+                           gmx_bool bQuiet)
 {
   gmx_large_int_t  *ibuf;
   int p;
   gmx_bool bCompatible;
 
-  if (NULL != log)
+  if (NULL != log && !bQuiet)
       fprintf(log,"Multi-checking %s ... ",name);
   
   if (ms == NULL)
@@ -182,7 +184,7 @@ void check_multi_large_int(FILE *log,const gmx_multisim_t *ms,
   
   if (bCompatible) 
   {
-      if (NULL != log)
+      if (NULL != log && !bQuiet)
           fprintf(log,"OK\n");
   }
   else 
@@ -342,7 +344,10 @@ static void comm_args(const t_commrec *cr,int *argc,char ***argv)
   
   if (!MASTER(cr))
     snew(*argv,*argc+1);
-  fprintf(stderr,"NODEID=%d argc=%d\n",cr->nodeid,*argc);
+  if (debug)
+  {
+      fprintf(debug,"NODEID=%d argc=%d\n",cr->nodeid,*argc);
+  }
   for(i=0; (i<*argc); i++) {
     if (MASTER(cr))
       len = strlen((*argv)[i])+1;
index a35ffd5de7e21289f778ae9ce740d2f91b6c1836..bbae1df69c79a73d71297276bf43988fe7d16854 100644 (file)
@@ -1041,6 +1041,8 @@ static void gen_local_top(const gmx_mtop_t *mtop,const t_inputrec *ir,
         }
         if (idef->il[F_POSRES].nr > nposre_old)
         {
+            /* Executing this line line stops gmxdump -sys working
+             * correctly. I'm not aware there's an elegant fix. */
             set_posres_params(idef,molb,nposre_old/2,natoms);
         }
         if (idef->il[F_FBPOSRES].nr > nfbposre_old)
index 356785630b2a155d3b60fdceaeebe5911d12acef..dcc917329173e491f88ed910cccfabef9bc62439 100644 (file)
@@ -152,6 +152,10 @@ const char *efpt_names[efptNR+1] = {
   "fep-lambdas", "mass-lambdas", "coul-lambdas", "vdw-lambdas", "bonded-lambdas", "restraint-lambdas", "temperature-lambdas", NULL
 };
 
+const char *efpt_singular_names[efptNR+1] = {
+  "fep-lambda", "mass-lambda", "coul-lambda", "vdw-lambda", "bonded-lambda", "restraint-lambda", "temperature-lambda", NULL
+};
+
 const char *elamstats_names[elamstatsNR+1] = {
   "no", "metropolis-transition", "barker-transition", "minvar", "wang-landau", "weighted-wang-landau", NULL
 };
index 9921ef31f79ad2e61dca101cc2c854e4f121d059..ec210de8f73881e3be8d3dedd5d90c41997524f1 100644 (file)
@@ -96,8 +96,11 @@ int gmx_setup(int *argc,char **argv,int *nnodes)
   (void) MPI_Get_processor_name( mpi_hostname, &resultlen );
  
 #ifdef GMX_LIB_MPI 
-  fprintf(stderr,"NNODES=%d, MYRANK=%d, HOSTNAME=%s\n",
-         mpi_num_nodes,mpi_my_rank,mpi_hostname);
+  if (debug)
+  {
+      fprintf(debug,"NNODES=%d, MYRANK=%d, HOSTNAME=%s\n",
+              mpi_num_nodes,mpi_my_rank,mpi_hostname);
+  }
 #endif
   
   *nnodes=mpi_num_nodes;
index 8e3b8debc185ccf527120223eb9809391cbcb9e0..c6255e34cda8fb667d76a4524f96231a299e40b9 100644 (file)
@@ -368,6 +368,7 @@ nb_kernel_ElecGB_VdwCSTab_GeomP1P1_VF_avx_128_fma_double
             FF               = _mm_macc_pd(_mm_macc_pd(twogbeps,H,G),gbeps,Fp);
             fgb              = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
             dvdatmp          = _mm_mul_pd(minushalf,_mm_macc_pd(fgb,r00,vgb));
+            dvdatmp          = _mm_unpacklo_pd(dvdatmp,_mm_setzero_pd());
             dvdasum          = _mm_add_pd(dvdasum,dvdatmp);
             gmx_mm_increment_1real_pd(dvda+jnrA,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj0,isaj0)));
             velec            = _mm_mul_pd(qq00,rinv00);
@@ -774,6 +775,7 @@ nb_kernel_ElecGB_VdwCSTab_GeomP1P1_F_avx_128_fma_double
             FF               = _mm_macc_pd(_mm_macc_pd(twogbeps,H,G),gbeps,Fp);
             fgb              = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
             dvdatmp          = _mm_mul_pd(minushalf,_mm_macc_pd(fgb,r00,vgb));
+            dvdatmp          = _mm_unpacklo_pd(dvdatmp,_mm_setzero_pd());
             dvdasum          = _mm_add_pd(dvdasum,dvdatmp);
             gmx_mm_increment_1real_pd(dvda+jnrA,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj0,isaj0)));
             velec            = _mm_mul_pd(qq00,rinv00);
index ea36c2a7293495c4dfcc7ff5d0721232a22aad4e..200a6f56fe33c21c639e42ae3bd01722dee3c15c 100644 (file)
@@ -326,6 +326,7 @@ nb_kernel_ElecGB_VdwLJ_GeomP1P1_VF_avx_128_fma_double
             FF               = _mm_macc_pd(_mm_macc_pd(twogbeps,H,G),gbeps,Fp);
             fgb              = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
             dvdatmp          = _mm_mul_pd(minushalf,_mm_macc_pd(fgb,r00,vgb));
+            dvdatmp          = _mm_unpacklo_pd(dvdatmp,_mm_setzero_pd());
             dvdasum          = _mm_add_pd(dvdasum,dvdatmp);
             gmx_mm_increment_1real_pd(dvda+jnrA,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj0,isaj0)));
             velec            = _mm_mul_pd(qq00,rinv00);
@@ -671,6 +672,7 @@ nb_kernel_ElecGB_VdwLJ_GeomP1P1_F_avx_128_fma_double
             FF               = _mm_macc_pd(_mm_macc_pd(twogbeps,H,G),gbeps,Fp);
             fgb              = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
             dvdatmp          = _mm_mul_pd(minushalf,_mm_macc_pd(fgb,r00,vgb));
+            dvdatmp          = _mm_unpacklo_pd(dvdatmp,_mm_setzero_pd());
             dvdasum          = _mm_add_pd(dvdasum,dvdatmp);
             gmx_mm_increment_1real_pd(dvda+jnrA,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj0,isaj0)));
             velec            = _mm_mul_pd(qq00,rinv00);
index 4d4396f10550fa995b332ebab214ae3321faba99..db102833b3eae06e5f8b41b4debd224fcfdcb41e 100644 (file)
@@ -296,6 +296,7 @@ nb_kernel_ElecGB_VdwNone_GeomP1P1_VF_avx_128_fma_double
             FF               = _mm_macc_pd(_mm_macc_pd(twogbeps,H,G),gbeps,Fp);
             fgb              = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
             dvdatmp          = _mm_mul_pd(minushalf,_mm_macc_pd(fgb,r00,vgb));
+            dvdatmp          = _mm_unpacklo_pd(dvdatmp,_mm_setzero_pd());
             dvdasum          = _mm_add_pd(dvdasum,dvdatmp);
             gmx_mm_increment_1real_pd(dvda+jnrA,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj0,isaj0)));
             velec            = _mm_mul_pd(qq00,rinv00);
@@ -605,6 +606,7 @@ nb_kernel_ElecGB_VdwNone_GeomP1P1_F_avx_128_fma_double
             FF               = _mm_macc_pd(_mm_macc_pd(twogbeps,H,G),gbeps,Fp);
             fgb              = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
             dvdatmp          = _mm_mul_pd(minushalf,_mm_macc_pd(fgb,r00,vgb));
+            dvdatmp          = _mm_unpacklo_pd(dvdatmp,_mm_setzero_pd());
             dvdasum          = _mm_add_pd(dvdasum,dvdatmp);
             gmx_mm_increment_1real_pd(dvda+jnrA,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj0,isaj0)));
             velec            = _mm_mul_pd(qq00,rinv00);
index 43f7f24fd8fb531c7126c9f935e1ac888bdec843..6405a27a2210f604384b7e20b5dcff69dad8a54b 100644 (file)
@@ -592,6 +592,9 @@ void
             FF               = _mm_macc_pd(_mm_macc_pd(twogbeps,H,G),gbeps,Fp);
             fgb              = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
             dvdatmp          = _mm_mul_pd(minushalf,_mm_macc_pd(fgb,r{I}{J},vgb));
+            /*                 #if ROUND == 'Epilogue' */
+            dvdatmp          = _mm_unpacklo_pd(dvdatmp,_mm_setzero_pd());
+            /*                 #endif */
             dvdasum          = _mm_add_pd(dvdasum,dvdatmp);
             /*             #if ROUND == 'Loop' */
             gmx_mm_increment_2real_swizzle_pd(dvda+jnrA,dvda+jnrB,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj{J},isaj{J})));
index d2eb10eb9cdb31339bd18725888fe228682651c8..bddbca0d1855559e23d7848e48f330443fa959d1 100644 (file)
@@ -421,6 +421,7 @@ nb_kernel_ElecGB_VdwCSTab_GeomP1P1_VF_avx_128_fma_single
             FF               = _mm_macc_ps(_mm_macc_ps(twogbeps,H,G),gbeps,Fp);
             fgb              = _mm_mul_ps(gbqqfactor,_mm_mul_ps(FF,gbscale));
             dvdatmp          = _mm_mul_ps(minushalf,_mm_macc_ps(fgb,r00,vgb));
+            dvdatmp          = _mm_andnot_ps(dummy_mask,dvdatmp);
             dvdasum          = _mm_add_ps(dvdasum,dvdatmp);
             /* The pointers to scratch make sure that this code with compilers that take gmx_restrict seriously (e.g. icc 13) really can't screw things up. */
             fjptrA             = (jnrlistA>=0) ? dvda+jnrA : scratch;
@@ -887,6 +888,7 @@ nb_kernel_ElecGB_VdwCSTab_GeomP1P1_F_avx_128_fma_single
             FF               = _mm_macc_ps(_mm_macc_ps(twogbeps,H,G),gbeps,Fp);
             fgb              = _mm_mul_ps(gbqqfactor,_mm_mul_ps(FF,gbscale));
             dvdatmp          = _mm_mul_ps(minushalf,_mm_macc_ps(fgb,r00,vgb));
+            dvdatmp          = _mm_andnot_ps(dummy_mask,dvdatmp);
             dvdasum          = _mm_add_ps(dvdasum,dvdatmp);
             /* The pointers to scratch make sure that this code with compilers that take gmx_restrict seriously (e.g. icc 13) really can't screw things up. */
             fjptrA             = (jnrlistA>=0) ? dvda+jnrA : scratch;
index a0def42c3d188147def2514db8f6e8a351a168a6..fc0ff76f4e5097b7712034f78baff0c3f76ea958 100644 (file)
@@ -381,6 +381,7 @@ nb_kernel_ElecGB_VdwLJ_GeomP1P1_VF_avx_128_fma_single
             FF               = _mm_macc_ps(_mm_macc_ps(twogbeps,H,G),gbeps,Fp);
             fgb              = _mm_mul_ps(gbqqfactor,_mm_mul_ps(FF,gbscale));
             dvdatmp          = _mm_mul_ps(minushalf,_mm_macc_ps(fgb,r00,vgb));
+            dvdatmp          = _mm_andnot_ps(dummy_mask,dvdatmp);
             dvdasum          = _mm_add_ps(dvdasum,dvdatmp);
             /* The pointers to scratch make sure that this code with compilers that take gmx_restrict seriously (e.g. icc 13) really can't screw things up. */
             fjptrA             = (jnrlistA>=0) ? dvda+jnrA : scratch;
@@ -790,6 +791,7 @@ nb_kernel_ElecGB_VdwLJ_GeomP1P1_F_avx_128_fma_single
             FF               = _mm_macc_ps(_mm_macc_ps(twogbeps,H,G),gbeps,Fp);
             fgb              = _mm_mul_ps(gbqqfactor,_mm_mul_ps(FF,gbscale));
             dvdatmp          = _mm_mul_ps(minushalf,_mm_macc_ps(fgb,r00,vgb));
+            dvdatmp          = _mm_andnot_ps(dummy_mask,dvdatmp);
             dvdasum          = _mm_add_ps(dvdasum,dvdatmp);
             /* The pointers to scratch make sure that this code with compilers that take gmx_restrict seriously (e.g. icc 13) really can't screw things up. */
             fjptrA             = (jnrlistA>=0) ? dvda+jnrA : scratch;
index 696a9dde11469c63a204a60e358fcb126a3e1cb4..2470c88c5a5c778919bddac4cb57b3c80606c6a2 100644 (file)
@@ -339,6 +339,7 @@ nb_kernel_ElecGB_VdwNone_GeomP1P1_VF_avx_128_fma_single
             FF               = _mm_macc_ps(_mm_macc_ps(twogbeps,H,G),gbeps,Fp);
             fgb              = _mm_mul_ps(gbqqfactor,_mm_mul_ps(FF,gbscale));
             dvdatmp          = _mm_mul_ps(minushalf,_mm_macc_ps(fgb,r00,vgb));
+            dvdatmp          = _mm_andnot_ps(dummy_mask,dvdatmp);
             dvdasum          = _mm_add_ps(dvdasum,dvdatmp);
             /* The pointers to scratch make sure that this code with compilers that take gmx_restrict seriously (e.g. icc 13) really can't screw things up. */
             fjptrA             = (jnrlistA>=0) ? dvda+jnrA : scratch;
@@ -700,6 +701,7 @@ nb_kernel_ElecGB_VdwNone_GeomP1P1_F_avx_128_fma_single
             FF               = _mm_macc_ps(_mm_macc_ps(twogbeps,H,G),gbeps,Fp);
             fgb              = _mm_mul_ps(gbqqfactor,_mm_mul_ps(FF,gbscale));
             dvdatmp          = _mm_mul_ps(minushalf,_mm_macc_ps(fgb,r00,vgb));
+            dvdatmp          = _mm_andnot_ps(dummy_mask,dvdatmp);
             dvdasum          = _mm_add_ps(dvdasum,dvdatmp);
             /* The pointers to scratch make sure that this code with compilers that take gmx_restrict seriously (e.g. icc 13) really can't screw things up. */
             fjptrA             = (jnrlistA>=0) ? dvda+jnrA : scratch;
index 24d7dcc3d5ec046917bd2bc2dbc049f6ce3fbd38..e99699cbbffcff16655224e87b5aeefc399212d3 100644 (file)
@@ -596,6 +596,9 @@ void
             FF               = _mm_macc_ps(_mm_macc_ps(twogbeps,H,G),gbeps,Fp);
             fgb              = _mm_mul_ps(gbqqfactor,_mm_mul_ps(FF,gbscale));
             dvdatmp          = _mm_mul_ps(minushalf,_mm_macc_ps(fgb,r{I}{J},vgb));
+            /*                 #if ROUND == 'Epilogue' */
+            dvdatmp          = _mm_andnot_ps(dummy_mask,dvdatmp);
+            /*                 #endif */
             dvdasum          = _mm_add_ps(dvdasum,dvdatmp);
             /*                 #if ROUND == 'Loop' */
             fjptrA           = dvda+jnrA;
index 3ab68aaedb747e5e5ea77473180ea329aa93a606..8188a7c0d95315a13b42890eb4159d355b5a7ded 100644 (file)
@@ -413,6 +413,7 @@ nb_kernel_ElecGB_VdwCSTab_GeomP1P1_VF_avx_256_double
             FF               = _mm256_add_pd(Fp,_mm256_mul_pd(gbeps,_mm256_add_pd(G,_mm256_add_pd(Heps,Heps))));
             fgb              = _mm256_mul_pd(gbqqfactor,_mm256_mul_pd(FF,gbscale));
             dvdatmp          = _mm256_mul_pd(minushalf,_mm256_add_pd(vgb,_mm256_mul_pd(fgb,r00)));
+            dvdatmp          = _mm256_andnot_ps(dummy_mask,dvdatmp);
             dvdasum          = _mm256_add_pd(dvdasum,dvdatmp);
             /* The pointers to scratch make sure that this code with compilers that take gmx_restrict seriously (e.g. icc 13) really can't screw things up. */
             fjptrA             = (jnrlistA>=0) ? dvda+jnrA : scratch;
@@ -876,6 +877,7 @@ nb_kernel_ElecGB_VdwCSTab_GeomP1P1_F_avx_256_double
             FF               = _mm256_add_pd(Fp,_mm256_mul_pd(gbeps,_mm256_add_pd(G,_mm256_add_pd(Heps,Heps))));
             fgb              = _mm256_mul_pd(gbqqfactor,_mm256_mul_pd(FF,gbscale));
             dvdatmp          = _mm256_mul_pd(minushalf,_mm256_add_pd(vgb,_mm256_mul_pd(fgb,r00)));
+            dvdatmp          = _mm256_andnot_ps(dummy_mask,dvdatmp);
             dvdasum          = _mm256_add_pd(dvdasum,dvdatmp);
             /* The pointers to scratch make sure that this code with compilers that take gmx_restrict seriously (e.g. icc 13) really can't screw things up. */
             fjptrA             = (jnrlistA>=0) ? dvda+jnrA : scratch;
index abb078218264047f347d7ae3230a47d36d410667..9edb654bddf411c67fef4e81b81692ab21941775 100644 (file)
@@ -381,6 +381,7 @@ nb_kernel_ElecGB_VdwLJ_GeomP1P1_VF_avx_256_double
             FF               = _mm256_add_pd(Fp,_mm256_mul_pd(gbeps,_mm256_add_pd(G,_mm256_add_pd(Heps,Heps))));
             fgb              = _mm256_mul_pd(gbqqfactor,_mm256_mul_pd(FF,gbscale));
             dvdatmp          = _mm256_mul_pd(minushalf,_mm256_add_pd(vgb,_mm256_mul_pd(fgb,r00)));
+            dvdatmp          = _mm256_andnot_ps(dummy_mask,dvdatmp);
             dvdasum          = _mm256_add_pd(dvdasum,dvdatmp);
             /* The pointers to scratch make sure that this code with compilers that take gmx_restrict seriously (e.g. icc 13) really can't screw things up. */
             fjptrA             = (jnrlistA>=0) ? dvda+jnrA : scratch;
@@ -793,6 +794,7 @@ nb_kernel_ElecGB_VdwLJ_GeomP1P1_F_avx_256_double
             FF               = _mm256_add_pd(Fp,_mm256_mul_pd(gbeps,_mm256_add_pd(G,_mm256_add_pd(Heps,Heps))));
             fgb              = _mm256_mul_pd(gbqqfactor,_mm256_mul_pd(FF,gbscale));
             dvdatmp          = _mm256_mul_pd(minushalf,_mm256_add_pd(vgb,_mm256_mul_pd(fgb,r00)));
+            dvdatmp          = _mm256_andnot_ps(dummy_mask,dvdatmp);
             dvdasum          = _mm256_add_pd(dvdasum,dvdatmp);
             /* The pointers to scratch make sure that this code with compilers that take gmx_restrict seriously (e.g. icc 13) really can't screw things up. */
             fjptrA             = (jnrlistA>=0) ? dvda+jnrA : scratch;
index 27c0bb96b2ece012f609ed02305ac24fcadfe699..40a10c2a31b68e6df0e6f62714d968bed522866a 100644 (file)
@@ -339,6 +339,7 @@ nb_kernel_ElecGB_VdwNone_GeomP1P1_VF_avx_256_double
             FF               = _mm256_add_pd(Fp,_mm256_mul_pd(gbeps,_mm256_add_pd(G,_mm256_add_pd(Heps,Heps))));
             fgb              = _mm256_mul_pd(gbqqfactor,_mm256_mul_pd(FF,gbscale));
             dvdatmp          = _mm256_mul_pd(minushalf,_mm256_add_pd(vgb,_mm256_mul_pd(fgb,r00)));
+            dvdatmp          = _mm256_andnot_ps(dummy_mask,dvdatmp);
             dvdasum          = _mm256_add_pd(dvdasum,dvdatmp);
             /* The pointers to scratch make sure that this code with compilers that take gmx_restrict seriously (e.g. icc 13) really can't screw things up. */
             fjptrA             = (jnrlistA>=0) ? dvda+jnrA : scratch;
@@ -703,6 +704,7 @@ nb_kernel_ElecGB_VdwNone_GeomP1P1_F_avx_256_double
             FF               = _mm256_add_pd(Fp,_mm256_mul_pd(gbeps,_mm256_add_pd(G,_mm256_add_pd(Heps,Heps))));
             fgb              = _mm256_mul_pd(gbqqfactor,_mm256_mul_pd(FF,gbscale));
             dvdatmp          = _mm256_mul_pd(minushalf,_mm256_add_pd(vgb,_mm256_mul_pd(fgb,r00)));
+            dvdatmp          = _mm256_andnot_ps(dummy_mask,dvdatmp);
             dvdasum          = _mm256_add_pd(dvdasum,dvdatmp);
             /* The pointers to scratch make sure that this code with compilers that take gmx_restrict seriously (e.g. icc 13) really can't screw things up. */
             fjptrA             = (jnrlistA>=0) ? dvda+jnrA : scratch;
index 9f36946353161cecea954211e171a9aae4b784f2..2f0e86719395d773f98f8e170853deca4475dff1 100644 (file)
@@ -594,6 +594,9 @@ void
             FF               = _mm256_add_pd(Fp,_mm256_mul_pd(gbeps,_mm256_add_pd(G,_mm256_add_pd(Heps,Heps))));
             fgb              = _mm256_mul_pd(gbqqfactor,_mm256_mul_pd(FF,gbscale));
             dvdatmp          = _mm256_mul_pd(minushalf,_mm256_add_pd(vgb,_mm256_mul_pd(fgb,r{I}{J})));
+            /*                 #if ROUND == 'Epilogue' */
+            dvdatmp          = _mm256_andnot_ps(dummy_mask,dvdatmp);
+            /*                 #endif */
             dvdasum          = _mm256_add_pd(dvdasum,dvdatmp);
             /*                 #if ROUND == 'Loop' */
             fjptrA           = dvda+jnrA;
index 26bc33c0a493fac6ee22095376bda604cec774d4..2156c94d180c8b0d4d363ae6da19b394f8143f7f 100644 (file)
@@ -506,6 +506,7 @@ nb_kernel_ElecGB_VdwCSTab_GeomP1P1_VF_avx_256_single
             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(gbeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
             fgb              = _mm256_mul_ps(gbqqfactor,_mm256_mul_ps(FF,gbscale));
             dvdatmp          = _mm256_mul_ps(minushalf,_mm256_add_ps(vgb,_mm256_mul_ps(fgb,r00)));
+            dvdatmp          = _mm256_andnot_ps(dummy_mask,dvdatmp);
             dvdasum          = _mm256_add_ps(dvdasum,dvdatmp);
             /* The pointers to scratch make sure that this code with compilers that take gmx_restrict seriously (e.g. icc 13) really can't screw things up. */
             fjptrA             = (jnrlistA>=0) ? dvda+jnrA : scratch;
@@ -1079,6 +1080,7 @@ nb_kernel_ElecGB_VdwCSTab_GeomP1P1_F_avx_256_single
             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(gbeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
             fgb              = _mm256_mul_ps(gbqqfactor,_mm256_mul_ps(FF,gbscale));
             dvdatmp          = _mm256_mul_ps(minushalf,_mm256_add_ps(vgb,_mm256_mul_ps(fgb,r00)));
+            dvdatmp          = _mm256_andnot_ps(dummy_mask,dvdatmp);
             dvdasum          = _mm256_add_ps(dvdasum,dvdatmp);
             /* The pointers to scratch make sure that this code with compilers that take gmx_restrict seriously (e.g. icc 13) really can't screw things up. */
             fjptrA             = (jnrlistA>=0) ? dvda+jnrA : scratch;
index f626f719200621bf6b1e032012b1f269bb4e617b..464ff1a4fa98df3fb02d40cb02381d04a32357fb 100644 (file)
@@ -457,6 +457,7 @@ nb_kernel_ElecGB_VdwLJ_GeomP1P1_VF_avx_256_single
             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(gbeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
             fgb              = _mm256_mul_ps(gbqqfactor,_mm256_mul_ps(FF,gbscale));
             dvdatmp          = _mm256_mul_ps(minushalf,_mm256_add_ps(vgb,_mm256_mul_ps(fgb,r00)));
+            dvdatmp          = _mm256_andnot_ps(dummy_mask,dvdatmp);
             dvdasum          = _mm256_add_ps(dvdasum,dvdatmp);
             /* The pointers to scratch make sure that this code with compilers that take gmx_restrict seriously (e.g. icc 13) really can't screw things up. */
             fjptrA             = (jnrlistA>=0) ? dvda+jnrA : scratch;
@@ -953,6 +954,7 @@ nb_kernel_ElecGB_VdwLJ_GeomP1P1_F_avx_256_single
             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(gbeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
             fgb              = _mm256_mul_ps(gbqqfactor,_mm256_mul_ps(FF,gbscale));
             dvdatmp          = _mm256_mul_ps(minushalf,_mm256_add_ps(vgb,_mm256_mul_ps(fgb,r00)));
+            dvdatmp          = _mm256_andnot_ps(dummy_mask,dvdatmp);
             dvdasum          = _mm256_add_ps(dvdasum,dvdatmp);
             /* The pointers to scratch make sure that this code with compilers that take gmx_restrict seriously (e.g. icc 13) really can't screw things up. */
             fjptrA             = (jnrlistA>=0) ? dvda+jnrA : scratch;
index f8bb1ffbcd249fa2e56b5771fe748e114c4881b4..2f7d64e61c5a21705c94c3442faf8f140b483c6c 100644 (file)
@@ -399,6 +399,7 @@ nb_kernel_ElecGB_VdwNone_GeomP1P1_VF_avx_256_single
             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(gbeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
             fgb              = _mm256_mul_ps(gbqqfactor,_mm256_mul_ps(FF,gbscale));
             dvdatmp          = _mm256_mul_ps(minushalf,_mm256_add_ps(vgb,_mm256_mul_ps(fgb,r00)));
+            dvdatmp          = _mm256_andnot_ps(dummy_mask,dvdatmp);
             dvdasum          = _mm256_add_ps(dvdasum,dvdatmp);
             /* The pointers to scratch make sure that this code with compilers that take gmx_restrict seriously (e.g. icc 13) really can't screw things up. */
             fjptrA             = (jnrlistA>=0) ? dvda+jnrA : scratch;
@@ -831,6 +832,7 @@ nb_kernel_ElecGB_VdwNone_GeomP1P1_F_avx_256_single
             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(gbeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
             fgb              = _mm256_mul_ps(gbqqfactor,_mm256_mul_ps(FF,gbscale));
             dvdatmp          = _mm256_mul_ps(minushalf,_mm256_add_ps(vgb,_mm256_mul_ps(fgb,r00)));
+            dvdatmp          = _mm256_andnot_ps(dummy_mask,dvdatmp);
             dvdasum          = _mm256_add_ps(dvdasum,dvdatmp);
             /* The pointers to scratch make sure that this code with compilers that take gmx_restrict seriously (e.g. icc 13) really can't screw things up. */
             fjptrA             = (jnrlistA>=0) ? dvda+jnrA : scratch;
index 89bfdd3514646bab46276d15bdaa493ffd873f85..6cc310d76db7abded10073d5b6ed350b963c9a60 100644 (file)
@@ -649,6 +649,9 @@ void
             FF               = _mm256_add_ps(Fp,_mm256_mul_ps(gbeps,_mm256_add_ps(G,_mm256_add_ps(Heps,Heps))));
             fgb              = _mm256_mul_ps(gbqqfactor,_mm256_mul_ps(FF,gbscale));
             dvdatmp          = _mm256_mul_ps(minushalf,_mm256_add_ps(vgb,_mm256_mul_ps(fgb,r{I}{J})));
+            /*                 #if ROUND == 'Epilogue' */
+            dvdatmp          = _mm256_andnot_ps(dummy_mask,dvdatmp);
+            /*                 #endif */
             dvdasum          = _mm256_add_ps(dvdasum,dvdatmp);
             /*                 #if ROUND == 'Loop' */
             fjptrA           = dvda+jnrA;
index 23ba2990df4d02737f0ab28b357671bdefa8fe8d..bddc5873d4eba690cd3369d5cf54c22f8c7312f0 100644 (file)
@@ -133,7 +133,7 @@ nb_kernel_ElecGB_VdwLJ_GeomP1P1_VF_c
         vgbsum           = 0.0;
         vvdwsum          = 0.0;
         dvdasum          = 0.0;
-
+        printf("inr=%d\n",inr);
         /* Start inner kernel loop */
         for(jidx=j_index_start; jidx<j_index_end; jidx++)
         {
@@ -197,9 +197,12 @@ nb_kernel_ElecGB_VdwLJ_GeomP1P1_VF_c
 
             FF               = Fp+Geps+2.0*Heps2;
             fgb              = gbqqfactor*FF*gbscale;
+            printf("  jnr=%d  fgb=%g\n",jnr,fgb);
             dvdatmp          = -0.5*(vgb+fgb*r00);
             dvdasum          = dvdasum + dvdatmp;
+            printf("  dvdatmp=%g\n",dvdatmp);
             dvda[jnr]        = dvdaj+dvdatmp*isaj0*isaj0;
+            printf("  dvda, jcontrib=%g\n",dvdatmp*isaj0*isaj0);
             velec            = qq00*rinv00;
             felec            = (velec*rinv00-fgb)*rinv00;
 
index a18d1c18495a1a7b68f3c5fc70515194a566fa7c..d0aa93072ab6a152315ae762952e87eb3a7d6015 100644 (file)
@@ -354,6 +354,7 @@ nb_kernel_ElecGB_VdwCSTab_GeomP1P1_VF_sse2_double
             FF               = _mm_add_pd(Fp,_mm_mul_pd(gbeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
             fgb              = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
             dvdatmp          = _mm_mul_pd(minushalf,_mm_add_pd(vgb,_mm_mul_pd(fgb,r00)));
+            dvdatmp          = _mm_unpacklo_pd(dvdatmp,_mm_setzero_pd());
             dvdasum          = _mm_add_pd(dvdasum,dvdatmp);
             gmx_mm_increment_1real_pd(dvda+jnrA,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj0,isaj0)));
             velec            = _mm_mul_pd(qq00,rinv00);
@@ -750,6 +751,7 @@ nb_kernel_ElecGB_VdwCSTab_GeomP1P1_F_sse2_double
             FF               = _mm_add_pd(Fp,_mm_mul_pd(gbeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
             fgb              = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
             dvdatmp          = _mm_mul_pd(minushalf,_mm_add_pd(vgb,_mm_mul_pd(fgb,r00)));
+            dvdatmp          = _mm_unpacklo_pd(dvdatmp,_mm_setzero_pd());
             dvdasum          = _mm_add_pd(dvdasum,dvdatmp);
             gmx_mm_increment_1real_pd(dvda+jnrA,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj0,isaj0)));
             velec            = _mm_mul_pd(qq00,rinv00);
index 2c6fa3646815f80c71012154651ce91538231577..b34776616d53d6b270779fca0858e31ce097c05c 100644 (file)
@@ -320,6 +320,7 @@ nb_kernel_ElecGB_VdwLJ_GeomP1P1_VF_sse2_double
             FF               = _mm_add_pd(Fp,_mm_mul_pd(gbeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
             fgb              = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
             dvdatmp          = _mm_mul_pd(minushalf,_mm_add_pd(vgb,_mm_mul_pd(fgb,r00)));
+            dvdatmp          = _mm_unpacklo_pd(dvdatmp,_mm_setzero_pd());
             dvdasum          = _mm_add_pd(dvdasum,dvdatmp);
             gmx_mm_increment_1real_pd(dvda+jnrA,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj0,isaj0)));
             velec            = _mm_mul_pd(qq00,rinv00);
@@ -661,6 +662,7 @@ nb_kernel_ElecGB_VdwLJ_GeomP1P1_F_sse2_double
             FF               = _mm_add_pd(Fp,_mm_mul_pd(gbeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
             fgb              = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
             dvdatmp          = _mm_mul_pd(minushalf,_mm_add_pd(vgb,_mm_mul_pd(fgb,r00)));
+            dvdatmp          = _mm_unpacklo_pd(dvdatmp,_mm_setzero_pd());
             dvdasum          = _mm_add_pd(dvdasum,dvdatmp);
             gmx_mm_increment_1real_pd(dvda+jnrA,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj0,isaj0)));
             velec            = _mm_mul_pd(qq00,rinv00);
index 830d40a2f0a6ad2383af15ab0f30a8cb116b0741..a5845eedd8a4a132b0c4de15bfe41defbb317241 100644 (file)
@@ -290,6 +290,7 @@ nb_kernel_ElecGB_VdwNone_GeomP1P1_VF_sse2_double
             FF               = _mm_add_pd(Fp,_mm_mul_pd(gbeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
             fgb              = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
             dvdatmp          = _mm_mul_pd(minushalf,_mm_add_pd(vgb,_mm_mul_pd(fgb,r00)));
+            dvdatmp          = _mm_unpacklo_pd(dvdatmp,_mm_setzero_pd());
             dvdasum          = _mm_add_pd(dvdasum,dvdatmp);
             gmx_mm_increment_1real_pd(dvda+jnrA,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj0,isaj0)));
             velec            = _mm_mul_pd(qq00,rinv00);
@@ -595,6 +596,7 @@ nb_kernel_ElecGB_VdwNone_GeomP1P1_F_sse2_double
             FF               = _mm_add_pd(Fp,_mm_mul_pd(gbeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
             fgb              = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
             dvdatmp          = _mm_mul_pd(minushalf,_mm_add_pd(vgb,_mm_mul_pd(fgb,r00)));
+            dvdatmp          = _mm_unpacklo_pd(dvdatmp,_mm_setzero_pd());
             dvdasum          = _mm_add_pd(dvdasum,dvdatmp);
             gmx_mm_increment_1real_pd(dvda+jnrA,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj0,isaj0)));
             velec            = _mm_mul_pd(qq00,rinv00);
index 4bf5952cbaa89e27750c5046f8b3261c94753ed8..e9fa63ae175c140635c2d3fe5fee836e5634899a 100644 (file)
@@ -583,6 +583,9 @@ void
             FF               = _mm_add_pd(Fp,_mm_mul_pd(gbeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
             fgb              = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
             dvdatmp          = _mm_mul_pd(minushalf,_mm_add_pd(vgb,_mm_mul_pd(fgb,r{I}{J})));
+            /*                 #if ROUND == 'Epilogue' */
+            dvdatmp          = _mm_unpacklo_pd(dvdatmp,_mm_setzero_pd());
+            /*                 #endif */
             dvdasum          = _mm_add_pd(dvdasum,dvdatmp);
             /*             #if ROUND == 'Loop' */
             gmx_mm_increment_2real_swizzle_pd(dvda+jnrA,dvda+jnrB,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj{J},isaj{J})));
index 2354469b729abea5cdbb196b5f1c79a878d08395..26bdb4cd3495a292e689505648600bf0f669dc01 100644 (file)
@@ -407,6 +407,7 @@ nb_kernel_ElecGB_VdwCSTab_GeomP1P1_VF_sse2_single
             FF               = _mm_add_ps(Fp,_mm_mul_ps(gbeps,_mm_add_ps(G,_mm_add_ps(Heps,Heps))));
             fgb              = _mm_mul_ps(gbqqfactor,_mm_mul_ps(FF,gbscale));
             dvdatmp          = _mm_mul_ps(minushalf,_mm_add_ps(vgb,_mm_mul_ps(fgb,r00)));
+            dvdatmp          = _mm_andnot_ps(dummy_mask,dvdatmp);
             dvdasum          = _mm_add_ps(dvdasum,dvdatmp);
             /* The pointers to scratch make sure that this code with compilers that take gmx_restrict seriously (e.g. icc 13) really can't screw things up. */
             fjptrA             = (jnrlistA>=0) ? dvda+jnrA : scratch;
@@ -863,6 +864,7 @@ nb_kernel_ElecGB_VdwCSTab_GeomP1P1_F_sse2_single
             FF               = _mm_add_ps(Fp,_mm_mul_ps(gbeps,_mm_add_ps(G,_mm_add_ps(Heps,Heps))));
             fgb              = _mm_mul_ps(gbqqfactor,_mm_mul_ps(FF,gbscale));
             dvdatmp          = _mm_mul_ps(minushalf,_mm_add_ps(vgb,_mm_mul_ps(fgb,r00)));
+            dvdatmp          = _mm_andnot_ps(dummy_mask,dvdatmp);
             dvdasum          = _mm_add_ps(dvdasum,dvdatmp);
             /* The pointers to scratch make sure that this code with compilers that take gmx_restrict seriously (e.g. icc 13) really can't screw things up. */
             fjptrA             = (jnrlistA>=0) ? dvda+jnrA : scratch;
index 4b8297188884489b5c5e86fc747833e0d359a150..b2c7e57c5ffd6dc20b31b5a6c8023bbf09a535b8 100644 (file)
@@ -375,6 +375,7 @@ nb_kernel_ElecGB_VdwLJ_GeomP1P1_VF_sse2_single
             FF               = _mm_add_ps(Fp,_mm_mul_ps(gbeps,_mm_add_ps(G,_mm_add_ps(Heps,Heps))));
             fgb              = _mm_mul_ps(gbqqfactor,_mm_mul_ps(FF,gbscale));
             dvdatmp          = _mm_mul_ps(minushalf,_mm_add_ps(vgb,_mm_mul_ps(fgb,r00)));
+            dvdatmp          = _mm_andnot_ps(dummy_mask,dvdatmp);
             dvdasum          = _mm_add_ps(dvdasum,dvdatmp);
             /* The pointers to scratch make sure that this code with compilers that take gmx_restrict seriously (e.g. icc 13) really can't screw things up. */
             fjptrA             = (jnrlistA>=0) ? dvda+jnrA : scratch;
@@ -780,6 +781,7 @@ nb_kernel_ElecGB_VdwLJ_GeomP1P1_F_sse2_single
             FF               = _mm_add_ps(Fp,_mm_mul_ps(gbeps,_mm_add_ps(G,_mm_add_ps(Heps,Heps))));
             fgb              = _mm_mul_ps(gbqqfactor,_mm_mul_ps(FF,gbscale));
             dvdatmp          = _mm_mul_ps(minushalf,_mm_add_ps(vgb,_mm_mul_ps(fgb,r00)));
+            dvdatmp          = _mm_andnot_ps(dummy_mask,dvdatmp);
             dvdasum          = _mm_add_ps(dvdasum,dvdatmp);
             /* The pointers to scratch make sure that this code with compilers that take gmx_restrict seriously (e.g. icc 13) really can't screw things up. */
             fjptrA             = (jnrlistA>=0) ? dvda+jnrA : scratch;
index cdc49ea118d005ee215e4a18c7c5e8df8c114c82..dd490338e1381a2bbeda3add3de48b257e799643 100644 (file)
@@ -333,6 +333,7 @@ nb_kernel_ElecGB_VdwNone_GeomP1P1_VF_sse2_single
             FF               = _mm_add_ps(Fp,_mm_mul_ps(gbeps,_mm_add_ps(G,_mm_add_ps(Heps,Heps))));
             fgb              = _mm_mul_ps(gbqqfactor,_mm_mul_ps(FF,gbscale));
             dvdatmp          = _mm_mul_ps(minushalf,_mm_add_ps(vgb,_mm_mul_ps(fgb,r00)));
+            dvdatmp          = _mm_andnot_ps(dummy_mask,dvdatmp);
             dvdasum          = _mm_add_ps(dvdasum,dvdatmp);
             /* The pointers to scratch make sure that this code with compilers that take gmx_restrict seriously (e.g. icc 13) really can't screw things up. */
             fjptrA             = (jnrlistA>=0) ? dvda+jnrA : scratch;
@@ -690,6 +691,7 @@ nb_kernel_ElecGB_VdwNone_GeomP1P1_F_sse2_single
             FF               = _mm_add_ps(Fp,_mm_mul_ps(gbeps,_mm_add_ps(G,_mm_add_ps(Heps,Heps))));
             fgb              = _mm_mul_ps(gbqqfactor,_mm_mul_ps(FF,gbscale));
             dvdatmp          = _mm_mul_ps(minushalf,_mm_add_ps(vgb,_mm_mul_ps(fgb,r00)));
+            dvdatmp          = _mm_andnot_ps(dummy_mask,dvdatmp);
             dvdasum          = _mm_add_ps(dvdasum,dvdatmp);
             /* The pointers to scratch make sure that this code with compilers that take gmx_restrict seriously (e.g. icc 13) really can't screw things up. */
             fjptrA             = (jnrlistA>=0) ? dvda+jnrA : scratch;
index edec7a374548afbae499dca7d10df43e3460f47f..00ff0ca56afb01b3239295fba3114ee6143ee30f 100644 (file)
@@ -583,6 +583,9 @@ void
             FF               = _mm_add_ps(Fp,_mm_mul_ps(gbeps,_mm_add_ps(G,_mm_add_ps(Heps,Heps))));
             fgb              = _mm_mul_ps(gbqqfactor,_mm_mul_ps(FF,gbscale));
             dvdatmp          = _mm_mul_ps(minushalf,_mm_add_ps(vgb,_mm_mul_ps(fgb,r{I}{J})));
+            /*                 #if ROUND == 'Epilogue' */
+            dvdatmp          = _mm_andnot_ps(dummy_mask,dvdatmp);
+            /*                 #endif */
             dvdasum          = _mm_add_ps(dvdasum,dvdatmp);
             /*                 #if ROUND == 'Loop' */
             fjptrA           = dvda+jnrA;
index c3e898e2a9222f838c60556a2bfdfa5740db07fb..ac0dee2a255ec4292787efe72ebf5c5f0ba99452 100644 (file)
@@ -354,6 +354,7 @@ nb_kernel_ElecGB_VdwCSTab_GeomP1P1_VF_sse4_1_double
             FF               = _mm_add_pd(Fp,_mm_mul_pd(gbeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
             fgb              = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
             dvdatmp          = _mm_mul_pd(minushalf,_mm_add_pd(vgb,_mm_mul_pd(fgb,r00)));
+            dvdatmp          = _mm_unpacklo_pd(dvdatmp,_mm_setzero_pd());
             dvdasum          = _mm_add_pd(dvdasum,dvdatmp);
             gmx_mm_increment_1real_pd(dvda+jnrA,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj0,isaj0)));
             velec            = _mm_mul_pd(qq00,rinv00);
@@ -750,6 +751,7 @@ nb_kernel_ElecGB_VdwCSTab_GeomP1P1_F_sse4_1_double
             FF               = _mm_add_pd(Fp,_mm_mul_pd(gbeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
             fgb              = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
             dvdatmp          = _mm_mul_pd(minushalf,_mm_add_pd(vgb,_mm_mul_pd(fgb,r00)));
+            dvdatmp          = _mm_unpacklo_pd(dvdatmp,_mm_setzero_pd());
             dvdasum          = _mm_add_pd(dvdasum,dvdatmp);
             gmx_mm_increment_1real_pd(dvda+jnrA,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj0,isaj0)));
             velec            = _mm_mul_pd(qq00,rinv00);
index 2e9e29e174b43456611613acd556c5db72f13164..8f91a0222666a83fb9871220755abd95d1b65160 100644 (file)
@@ -320,6 +320,7 @@ nb_kernel_ElecGB_VdwLJ_GeomP1P1_VF_sse4_1_double
             FF               = _mm_add_pd(Fp,_mm_mul_pd(gbeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
             fgb              = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
             dvdatmp          = _mm_mul_pd(minushalf,_mm_add_pd(vgb,_mm_mul_pd(fgb,r00)));
+            dvdatmp          = _mm_unpacklo_pd(dvdatmp,_mm_setzero_pd());
             dvdasum          = _mm_add_pd(dvdasum,dvdatmp);
             gmx_mm_increment_1real_pd(dvda+jnrA,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj0,isaj0)));
             velec            = _mm_mul_pd(qq00,rinv00);
@@ -661,6 +662,7 @@ nb_kernel_ElecGB_VdwLJ_GeomP1P1_F_sse4_1_double
             FF               = _mm_add_pd(Fp,_mm_mul_pd(gbeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
             fgb              = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
             dvdatmp          = _mm_mul_pd(minushalf,_mm_add_pd(vgb,_mm_mul_pd(fgb,r00)));
+            dvdatmp          = _mm_unpacklo_pd(dvdatmp,_mm_setzero_pd());
             dvdasum          = _mm_add_pd(dvdasum,dvdatmp);
             gmx_mm_increment_1real_pd(dvda+jnrA,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj0,isaj0)));
             velec            = _mm_mul_pd(qq00,rinv00);
index be01ba33b0e6fa3689a2b4895ca982d23c5bcdc9..99d358b661093c506b5d4c5b4a3ac55e028c7299 100644 (file)
@@ -290,6 +290,7 @@ nb_kernel_ElecGB_VdwNone_GeomP1P1_VF_sse4_1_double
             FF               = _mm_add_pd(Fp,_mm_mul_pd(gbeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
             fgb              = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
             dvdatmp          = _mm_mul_pd(minushalf,_mm_add_pd(vgb,_mm_mul_pd(fgb,r00)));
+            dvdatmp          = _mm_unpacklo_pd(dvdatmp,_mm_setzero_pd());
             dvdasum          = _mm_add_pd(dvdasum,dvdatmp);
             gmx_mm_increment_1real_pd(dvda+jnrA,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj0,isaj0)));
             velec            = _mm_mul_pd(qq00,rinv00);
@@ -595,6 +596,7 @@ nb_kernel_ElecGB_VdwNone_GeomP1P1_F_sse4_1_double
             FF               = _mm_add_pd(Fp,_mm_mul_pd(gbeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
             fgb              = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
             dvdatmp          = _mm_mul_pd(minushalf,_mm_add_pd(vgb,_mm_mul_pd(fgb,r00)));
+            dvdatmp          = _mm_unpacklo_pd(dvdatmp,_mm_setzero_pd());
             dvdasum          = _mm_add_pd(dvdasum,dvdatmp);
             gmx_mm_increment_1real_pd(dvda+jnrA,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj0,isaj0)));
             velec            = _mm_mul_pd(qq00,rinv00);
index 744783556837baef451265ddcdc7c6edf259a6b7..82a6f96d78ef9ea2efa119beb3cf502b973676fe 100644 (file)
@@ -583,6 +583,9 @@ void
             FF               = _mm_add_pd(Fp,_mm_mul_pd(gbeps,_mm_add_pd(G,_mm_add_pd(Heps,Heps))));
             fgb              = _mm_mul_pd(gbqqfactor,_mm_mul_pd(FF,gbscale));
             dvdatmp          = _mm_mul_pd(minushalf,_mm_add_pd(vgb,_mm_mul_pd(fgb,r{I}{J})));
+            /*                 #if ROUND == 'Epilogue' */
+            dvdatmp          = _mm_unpacklo_pd(dvdatmp,_mm_setzero_pd());
+            /*                 #endif */
             dvdasum          = _mm_add_pd(dvdasum,dvdatmp);
             /*             #if ROUND == 'Loop' */
             gmx_mm_increment_2real_swizzle_pd(dvda+jnrA,dvda+jnrB,_mm_mul_pd(dvdatmp,_mm_mul_pd(isaj{J},isaj{J})));
index 9d47405368111edc331dc0dc091dc9e07896e072..81a6e97b776d8b2b4c85880385d4f319f00bbdc4 100644 (file)
@@ -405,6 +405,7 @@ nb_kernel_ElecGB_VdwCSTab_GeomP1P1_VF_sse4_1_single
             FF               = _mm_add_ps(Fp,_mm_mul_ps(gbeps,_mm_add_ps(G,_mm_add_ps(Heps,Heps))));
             fgb              = _mm_mul_ps(gbqqfactor,_mm_mul_ps(FF,gbscale));
             dvdatmp          = _mm_mul_ps(minushalf,_mm_add_ps(vgb,_mm_mul_ps(fgb,r00)));
+            dvdatmp          = _mm_andnot_ps(dummy_mask,dvdatmp);
             dvdasum          = _mm_add_ps(dvdasum,dvdatmp);
             /* The pointers to scratch make sure that this code with compilers that take gmx_restrict seriously (e.g. icc 13) really can't screw things up. */
             fjptrA             = (jnrlistA>=0) ? dvda+jnrA : scratch;
@@ -859,6 +860,7 @@ nb_kernel_ElecGB_VdwCSTab_GeomP1P1_F_sse4_1_single
             FF               = _mm_add_ps(Fp,_mm_mul_ps(gbeps,_mm_add_ps(G,_mm_add_ps(Heps,Heps))));
             fgb              = _mm_mul_ps(gbqqfactor,_mm_mul_ps(FF,gbscale));
             dvdatmp          = _mm_mul_ps(minushalf,_mm_add_ps(vgb,_mm_mul_ps(fgb,r00)));
+            dvdatmp          = _mm_andnot_ps(dummy_mask,dvdatmp);
             dvdasum          = _mm_add_ps(dvdasum,dvdatmp);
             /* The pointers to scratch make sure that this code with compilers that take gmx_restrict seriously (e.g. icc 13) really can't screw things up. */
             fjptrA             = (jnrlistA>=0) ? dvda+jnrA : scratch;
index 4f80354d9156d5f60e112b8e1e4185bee90fc57e..e7800d7733b49328c77d91b79c21089288b16e11 100644 (file)
@@ -373,6 +373,7 @@ nb_kernel_ElecGB_VdwLJ_GeomP1P1_VF_sse4_1_single
             FF               = _mm_add_ps(Fp,_mm_mul_ps(gbeps,_mm_add_ps(G,_mm_add_ps(Heps,Heps))));
             fgb              = _mm_mul_ps(gbqqfactor,_mm_mul_ps(FF,gbscale));
             dvdatmp          = _mm_mul_ps(minushalf,_mm_add_ps(vgb,_mm_mul_ps(fgb,r00)));
+            dvdatmp          = _mm_andnot_ps(dummy_mask,dvdatmp);
             dvdasum          = _mm_add_ps(dvdasum,dvdatmp);
             /* The pointers to scratch make sure that this code with compilers that take gmx_restrict seriously (e.g. icc 13) really can't screw things up. */
             fjptrA             = (jnrlistA>=0) ? dvda+jnrA : scratch;
@@ -776,6 +777,7 @@ nb_kernel_ElecGB_VdwLJ_GeomP1P1_F_sse4_1_single
             FF               = _mm_add_ps(Fp,_mm_mul_ps(gbeps,_mm_add_ps(G,_mm_add_ps(Heps,Heps))));
             fgb              = _mm_mul_ps(gbqqfactor,_mm_mul_ps(FF,gbscale));
             dvdatmp          = _mm_mul_ps(minushalf,_mm_add_ps(vgb,_mm_mul_ps(fgb,r00)));
+            dvdatmp          = _mm_andnot_ps(dummy_mask,dvdatmp);
             dvdasum          = _mm_add_ps(dvdasum,dvdatmp);
             /* The pointers to scratch make sure that this code with compilers that take gmx_restrict seriously (e.g. icc 13) really can't screw things up. */
             fjptrA             = (jnrlistA>=0) ? dvda+jnrA : scratch;
index 1a98520afb02bfbcd2f0162d9f5def87b579b1c5..049ba10ab972bf47caa151a1ab714a72fcfe3499 100644 (file)
@@ -331,6 +331,7 @@ nb_kernel_ElecGB_VdwNone_GeomP1P1_VF_sse4_1_single
             FF               = _mm_add_ps(Fp,_mm_mul_ps(gbeps,_mm_add_ps(G,_mm_add_ps(Heps,Heps))));
             fgb              = _mm_mul_ps(gbqqfactor,_mm_mul_ps(FF,gbscale));
             dvdatmp          = _mm_mul_ps(minushalf,_mm_add_ps(vgb,_mm_mul_ps(fgb,r00)));
+            dvdatmp          = _mm_andnot_ps(dummy_mask,dvdatmp);
             dvdasum          = _mm_add_ps(dvdasum,dvdatmp);
             /* The pointers to scratch make sure that this code with compilers that take gmx_restrict seriously (e.g. icc 13) really can't screw things up. */
             fjptrA             = (jnrlistA>=0) ? dvda+jnrA : scratch;
@@ -686,6 +687,7 @@ nb_kernel_ElecGB_VdwNone_GeomP1P1_F_sse4_1_single
             FF               = _mm_add_ps(Fp,_mm_mul_ps(gbeps,_mm_add_ps(G,_mm_add_ps(Heps,Heps))));
             fgb              = _mm_mul_ps(gbqqfactor,_mm_mul_ps(FF,gbscale));
             dvdatmp          = _mm_mul_ps(minushalf,_mm_add_ps(vgb,_mm_mul_ps(fgb,r00)));
+            dvdatmp          = _mm_andnot_ps(dummy_mask,dvdatmp);
             dvdasum          = _mm_add_ps(dvdasum,dvdatmp);
             /* The pointers to scratch make sure that this code with compilers that take gmx_restrict seriously (e.g. icc 13) really can't screw things up. */
             fjptrA             = (jnrlistA>=0) ? dvda+jnrA : scratch;
index 9214f45ad8157e365ea8f91bdd1e2c72b6bf9ebe..ee40d8317232e87c72b7c29b8794f4ad7fe2a005 100644 (file)
@@ -582,6 +582,9 @@ void
             FF               = _mm_add_ps(Fp,_mm_mul_ps(gbeps,_mm_add_ps(G,_mm_add_ps(Heps,Heps))));
             fgb              = _mm_mul_ps(gbqqfactor,_mm_mul_ps(FF,gbscale));
             dvdatmp          = _mm_mul_ps(minushalf,_mm_add_ps(vgb,_mm_mul_ps(fgb,r{I}{J})));
+            /*                 #if ROUND == 'Epilogue' */
+            dvdatmp          = _mm_andnot_ps(dummy_mask,dvdatmp);
+            /*                 #endif */
             dvdasum          = _mm_add_ps(dvdasum,dvdatmp);
             /*                 #if ROUND == 'Loop' */
             fjptrA           = dvda+jnrA;
index d57d9ac7e85c3f72bb21549a300c1cfe077d74ec..9fa8a05b486e5c9dc7c565957c76593b60925116 100644 (file)
@@ -224,10 +224,12 @@ void init_orires(FILE *fplog,const gmx_mtop_t *mtop,
         fprintf(fplog,"  the orientation restraints are ensemble averaged over %d systems\n",ms->nsim);
         
         check_multi_int(fplog,ms,od->nr,
-                        "the number of orientation restraints");
+                        "the number of orientation restraints",
+                        FALSE);
         check_multi_int(fplog,ms,od->nref,
-                        "the number of fit atoms for orientation restraining");
-        check_multi_int(fplog,ms,ir->nsteps,"nsteps");
+                        "the number of fit atoms for orientation restraining",
+                        FALSE);
+        check_multi_int(fplog,ms,ir->nsteps,"nsteps",FALSE);
         /* Copy the reference coordinates from the master to the other nodes */
         gmx_sum_sim(DIM*od->nref,od->xref[0],ms);
     }
index dc6eebf60822c24d9f34aa7953ce415190c589a4..bd7a9698afe4f265c61695a90ad992274d383814 100644 (file)
@@ -73,7 +73,7 @@
 static const char *tpx_tag = TPX_TAG_RELEASE;
 
 /* This number should be increased whenever the file format changes! */
-static const int tpx_version = 91;
+static const int tpx_version = 92;
 
 /* This number should only be increased when you edit the TOPOLOGY section
  * or the HEADER of the tpx format.
@@ -251,14 +251,18 @@ static void do_pullgrp(t_fileio *fio, t_pullgrp *pgrp, gmx_bool bRead,
   }
 }
 
-static void do_expandedvals(t_fileio *fio,t_expanded *expand,int n_lambda, gmx_bool bRead, int file_version)
+static void do_expandedvals(t_fileio *fio,t_expanded *expand,t_lambda *fepvals, gmx_bool bRead, int file_version)
 {
   /* i is used in the ndo_double macro*/
   int i;
   real fv;
   gmx_bool bDum=TRUE;
   real rdum;
+  int n_lambda=fepvals->n_lambda;
 
+  /* reset the lambda calculation window */
+  fepvals->lambda_start_n = 0;
+  fepvals->lambda_stop_n = n_lambda;
   if (file_version >= 79)
   {
       if (n_lambda>0)
@@ -326,6 +330,7 @@ static void do_fepvals(t_fileio *fio,t_lambda *fepvals,gmx_bool bRead, int file_
   real rdum;
 
   /* free energy values */
+
   if (file_version >= 79)
   {
       gmx_fio_do_int(fio,fepvals->init_fep_state);
@@ -367,23 +372,41 @@ static void do_fepvals(t_fileio *fio,t_lambda *fepvals,gmx_bool bRead, int file_
   else if (file_version >= 64)
   {
       gmx_fio_do_int(fio,fepvals->n_lambda);
-      snew(fepvals->all_lambda,efptNR);
       if (bRead)
       {
-          snew(fepvals->all_lambda[efptFEP],fepvals->n_lambda);
+          int g;
+
+          snew(fepvals->all_lambda,efptNR);
+          /* still allocate the all_lambda array's contents. */
+          for(g=0;g<efptNR;g++)
+          {
+              if (fepvals->n_lambda > 0) {
+                  snew(fepvals->all_lambda[g],fepvals->n_lambda);
+              }
+          }
       }
-      bDum=gmx_fio_ndo_double(fio,fepvals->all_lambda[efptFEP],fepvals->n_lambda);
+      bDum=gmx_fio_ndo_double(fio,fepvals->all_lambda[efptFEP],
+                              fepvals->n_lambda);
       if (fepvals->init_lambda >= 0)
       {
+          int g,h;
+
           fepvals->separate_dvdl[efptFEP] = TRUE;
-      }
-      /* still allocate the all_lambda array's contents. */
-      for (g=0;g<efptNR;g++)
-      {
-          if (fepvals->n_lambda > 0) {
-              if (bRead)
+
+          if (bRead)
+          {
+              /* copy the contents of the efptFEP lambda component to all
+                 the other components */
+              for(g=0;g<efptNR;g++)
               {
-                  snew(fepvals->all_lambda[g],fepvals->n_lambda);
+                  for(h=0;h<fepvals->n_lambda;h++)
+                  {
+                      if (g!=efptFEP)
+                      {
+                          fepvals->all_lambda[g][h] =
+                                    fepvals->all_lambda[efptFEP][h];
+                      }
+                  }
               }
           }
       }
@@ -482,6 +505,38 @@ static void do_fepvals(t_fileio *fio,t_lambda *fepvals,gmx_bool bRead, int file_
   {
       fepvals->bPrintEnergy = FALSE;
   }
+
+  /* handle lambda_neighbors */
+  if ((file_version >= 83 && file_version < 90) || file_version >= 92 )
+  {
+      gmx_fio_do_int(fio,fepvals->lambda_neighbors);
+      if ( (fepvals->lambda_neighbors >= 0) && (fepvals->init_fep_state>=0) &&
+           (fepvals->init_lambda < 0) )
+      {
+          fepvals->lambda_start_n = (fepvals->init_fep_state -
+                                     fepvals->lambda_neighbors);
+          fepvals->lambda_stop_n = (fepvals->init_fep_state +
+                                    fepvals->lambda_neighbors + 1);
+          if (fepvals->lambda_start_n < 0)
+          {
+              fepvals->lambda_start_n = 0;;
+          }
+          if (fepvals->lambda_stop_n >= fepvals->n_lambda)
+          {
+              fepvals->lambda_stop_n = fepvals->n_lambda;
+          }
+      }
+      else
+      {
+          fepvals->lambda_start_n = 0;
+          fepvals->lambda_stop_n = fepvals->n_lambda;
+      }
+  }
+  else
+  {
+      fepvals->lambda_start_n = 0;
+      fepvals->lambda_stop_n = fepvals->n_lambda;
+  }
 }
 
 static void do_pull(t_fileio *fio, t_pull *pull,gmx_bool bRead, int file_version)
@@ -968,7 +1023,7 @@ static void do_inputrec(t_fileio *fio, t_inputrec *ir,gmx_bool bRead,
     }
     if (ir->bExpanded)
     {
-        do_expandedvals(fio,ir->expandedvals,ir->fepvals->n_lambda,bRead,file_version);
+        do_expandedvals(fio,ir->expandedvals,ir->fepvals,bRead,file_version);
     }
     if (file_version >= 57) {
       gmx_fio_do_int(fio,ir->eDisre); 
index 2f4218c6641586a0014e5f149fc9f3e17116f214..82922dce52124ae79373b0906038ac4ed2817d58 100644 (file)
@@ -562,6 +562,20 @@ static void pr_fepvals(FILE *fp,int indent,t_lambda *fep, gmx_bool bMDPformat)
     if (fep->n_lambda > 0)
     {
         pr_indent(fp,indent);
+        fprintf(fp,"separate-dvdl%s\n",bMDPformat ? " = " : ":");
+        for(i=0; i<efptNR; i++)
+        {
+            fprintf(fp,"%18s = ",efpt_names[i]);
+            if (fep->separate_dvdl[i])
+            {
+                fprintf(fp,"  TRUE");
+            }
+            else
+            {
+                fprintf(fp,"  FALSE");
+            }
+            fprintf(fp,"\n");
+        }
         fprintf(fp,"all-lambdas%s\n",bMDPformat ? " = " : ":");
         for(i=0; i<efptNR; i++) {
             fprintf(fp,"%18s = ",efpt_names[i]);
@@ -572,6 +586,7 @@ static void pr_fepvals(FILE *fp,int indent,t_lambda *fep, gmx_bool bMDPformat)
             fprintf(fp,"\n");
         }
     }
+    PI("calc-lambda-neighbors",fep->lambda_neighbors);
 
     PR("sc-alpha",fep->sc_alpha);
     PS("bScCoul",EBOOL(fep->bScCoul));
index da20b6700cdffbc1eea3dc902f393f1119f5060e..68f9ce294b8216a474414501f643cd7a4ea8de99 100644 (file)
@@ -428,11 +428,29 @@ void check_ir(const char *mdparin,t_inputrec *ir, t_gromppopts *opts,
                 }
             }
         }
-        else if (ir->nstenergy > 0 && ir->nstcalcenergy > ir->nstenergy)
+        else if ( (ir->nstenergy > 0 && ir->nstcalcenergy > ir->nstenergy) ||
+                  (ir->efep != efepNO && ir->fepvals->nstdhdl > 0 &&
+                   (ir->nstcalcenergy > ir->fepvals->nstdhdl) ) )
+
         {
+            const char *nsten="nstenergy";
+            const char *nstdh="nstdhdl";
+            const char *min_name=nsten;
+            int min_nst=ir->nstenergy;
+
+            /* find the smallest of ( nstenergy, nstdhdl ) */
+            if (ir->efep != efepNO && ir->fepvals->nstdhdl > 0 &&
+                (ir->fepvals->nstdhdl < ir->nstenergy) )
+            {
+                min_nst=ir->fepvals->nstdhdl;
+                min_name=nstdh;
+            }
             /* If the user sets nstenergy small, we should respect that */
-            sprintf(warn_buf,"Setting nstcalcenergy (%d) equal to nstenergy (%d)",ir->nstcalcenergy,ir->nstenergy);
-            ir->nstcalcenergy = ir->nstenergy;
+            sprintf(warn_buf,
+                    "Setting nstcalcenergy (%d) equal to %s (%d)",
+                    ir->nstcalcenergy,min_name, min_nst);
+            warning_note(wi,warn_buf);
+            ir->nstcalcenergy = min_nst;
         }
 
         if (ir->epc != epcNO)
@@ -453,13 +471,8 @@ void check_ir(const char *mdparin,t_inputrec *ir, t_gromppopts *opts,
             }
         }
 
-        if (ir->nstcalcenergy > 1)
+        if (ir->nstcalcenergy > 0)
         {
-            /* for storing exact averages nstenergy should be
-             * a multiple of nstcalcenergy
-             */
-            check_nst("nstcalcenergy",ir->nstcalcenergy,
-                      "nstenergy",&ir->nstenergy,wi);
             if (ir->efep != efepNO)
             {
                 /* nstdhdl should be a multiple of nstcalcenergy */
@@ -467,8 +480,13 @@ void check_ir(const char *mdparin,t_inputrec *ir, t_gromppopts *opts,
                           "nstdhdl",&ir->fepvals->nstdhdl,wi);
                 /* nstexpanded should be a multiple of nstcalcenergy */
                 check_nst("nstcalcenergy",ir->nstcalcenergy,
-                          "nstdhdl",&ir->expandedvals->nstexpanded,wi);
+                          "nstexpanded",&ir->expandedvals->nstexpanded,wi);
             }
+            /* for storing exact averages nstenergy should be
+             * a multiple of nstcalcenergy
+             */
+            check_nst("nstcalcenergy",ir->nstcalcenergy,
+                      "nstenergy",&ir->nstenergy,wi);
         }
     }
 
@@ -560,7 +578,7 @@ void check_ir(const char *mdparin,t_inputrec *ir, t_gromppopts *opts,
       }
 
       sprintf(err_buf,"Can't use postive delta-lambda (%g) if initial state/lambda does not start at zero",fep->delta_lambda);
-      CHECK(fep->delta_lambda > 0 && ((fep->init_fep_state !=0) ||  (fep->init_lambda !=0)));
+      CHECK(fep->delta_lambda > 0 && ((fep->init_fep_state > 0) ||  (fep->init_lambda > 0)));
 
       sprintf(err_buf,"Can't use postive delta-lambda (%g) with expanded ensemble simulations",fep->delta_lambda);
       CHECK(fep->delta_lambda > 0 && (ir->efep == efepEXPANDED));
@@ -569,8 +587,50 @@ void check_ir(const char *mdparin,t_inputrec *ir, t_gromppopts *opts,
       CHECK(ir->coulombtype==eelEWALD);
 
       /* check validty of lambda inputs */
-      sprintf(err_buf,"initial thermodynamic state %d does not exist, only goes to %d",fep->init_fep_state,fep->n_lambda);
-      CHECK((fep->init_fep_state > fep->n_lambda));
+      if (fep->n_lambda == 0)
+      {
+          /* Clear output in case of no states:*/
+          sprintf(err_buf,"init-lambda-state set to %d: no lambda states are defined.",fep->init_fep_state);
+          CHECK((fep->init_fep_state>=0) && (fep->n_lambda==0));
+      }
+      else
+      {
+          sprintf(err_buf,"initial thermodynamic state %d does not exist, only goes to %d",fep->init_fep_state,fep->n_lambda-1);
+          CHECK((fep->init_fep_state >= fep->n_lambda));
+      }
+
+      sprintf(err_buf,"Lambda state must be set, either with init-lambda-state or with init-lambda");
+      CHECK((fep->init_fep_state < 0) && (fep->init_lambda <0));
+
+      sprintf(err_buf,"init-lambda=%g while init-lambda-state=%d. Lambda state must be set either with init-lambda-state or with init-lambda, but not both",
+              fep->init_lambda, fep->init_fep_state);
+      CHECK((fep->init_fep_state >= 0) && (fep->init_lambda >= 0));
+
+
+
+      if((fep->init_lambda >= 0) && (fep->delta_lambda == 0))
+      {
+          int n_lambda_terms;
+          n_lambda_terms=0;
+          for (i=0;i<efptNR;i++)
+          {
+              if (fep->separate_dvdl[i])
+              {
+                  n_lambda_terms++;
+              }
+          }
+          if (n_lambda_terms > 1)
+          {
+              sprintf(warn_buf,"If lambda vector states (fep-lambdas, coul-lambdas etc.) are set, don't use init-lambda to set lambda state (except for slow growth). Use init-lambda-state instead.");
+              warning(wi, warn_buf);
+          }
+
+          if (n_lambda_terms < 2 && fep->n_lambda > 0)
+          {
+              warning_note(wi,
+                           "init-lambda is deprecated for setting lambda state (except for slow growth). Use init-lambda-state instead.");
+          }
+      }
 
       for (j=0;j<efptNR;j++)
       {
@@ -1305,7 +1365,7 @@ static void do_fep_params(t_inputrec *ir, char fep_lambda[][STRLEN],char weights
     /* "fep-vals" is either zero or the full number. If zero, we'll need to define fep-lambdas for internal
        bookkeeping -- for now, init_lambda */
 
-    if ((nfep[efptFEP] == 0) && (fep->init_lambda >= 0) && (fep->init_lambda <= 1))
+    if ((nfep[efptFEP] == 0) && (fep->init_lambda >= 0))
     {
         for (i=0;i<fep->n_lambda;i++)
         {
@@ -1842,9 +1902,9 @@ void get_ir(const char *mdparin,const char *mdparout,
   RTYPE ("init-lambda", fep->init_lambda,-1); /* start with -1 so
                                                  we can recognize if
                                                  it was not entered */
-  ITYPE ("init-lambda-state", fep->init_fep_state,0);
+  ITYPE ("init-lambda-state", fep->init_fep_state,-1);
   RTYPE ("delta-lambda",fep->delta_lambda,0.0);
-  ITYPE ("nstdhdl",fep->nstdhdl, 100);
+  ITYPE ("nstdhdl",fep->nstdhdl, 50);
   STYPE ("fep-lambdas", fep_lambda[efptFEP], NULL);
   STYPE ("mass-lambdas", fep_lambda[efptMASS], NULL);
   STYPE ("coul-lambdas", fep_lambda[efptCOUL], NULL);
@@ -1852,6 +1912,7 @@ void get_ir(const char *mdparin,const char *mdparout,
   STYPE ("bonded-lambdas", fep_lambda[efptBONDED], NULL);
   STYPE ("restraint-lambdas", fep_lambda[efptRESTRAINT], NULL);
   STYPE ("temperature-lambdas", fep_lambda[efptTEMPERATURE], NULL);
+  ITYPE ("calc-lambda-neighbors",fep->lambda_neighbors, 1);
   STYPE ("init-lambda-weights",lambda_weights,NULL);
   EETYPE("dhdl-print-energy", fep->bPrintEnergy, yesno_names);
   RTYPE ("sc-alpha",fep->sc_alpha,0.0);
@@ -2681,16 +2742,13 @@ void do_index(const char* mdparin, const char *ndx,
           }
           if ((ir->epc==epcMTTK) && (ir->etc>etcNO))
           {
-              int mincouple;
-              mincouple = ir->nsttcouple;
-              if (ir->nstpcouple < mincouple)
+              if (ir->nstpcouple != ir->nsttcouple)
               {
-                  mincouple = ir->nstpcouple;
+                  int mincouple = min(ir->nstpcouple,ir->nsttcouple);
+                  ir->nstpcouple = ir->nsttcouple = mincouple;
+                  sprintf(warn_buf,"for current Trotter decomposition methods with vv, nsttcouple and nstpcouple must be equal.  Both have been reset to min(nsttcouple,nstpcouple) = %d",mincouple);
+                  warning_note(wi,warn_buf);
               }
-              ir->nstpcouple = mincouple;
-              ir->nsttcouple = mincouple;
-              sprintf(warn_buf,"for current Trotter decomposition methods with vv, nsttcouple and nstpcouple must be equal.  Both have been reset to min(nsttcouple,nstpcouple) = %d",mincouple);
-              warning_note(wi,warn_buf);
           }
       }
       /* velocity verlet with averaged kinetic energy KE = 0.5*(v(t+1/2) - v(t-1/2)) is implemented
index 9648f68e653b3fbfcee2171b48ec5962ce33754d..646c7d1830b8bce42b83f9582aafbf33e6a96908 100644 (file)
@@ -45,12 +45,14 @@ extern "C" {
 #endif
 
 void init_disres(FILE *fplog,const gmx_mtop_t *mtop,
-                       t_inputrec *ir,const t_commrec *cr,gmx_bool bPartDecomp,
-                       t_fcdata *fcd,t_state *state);
+                 t_inputrec *ir,const t_commrec *cr,gmx_bool bPartDecomp,
+                 t_fcdata *fcd,t_state *state, gmx_bool bIsREMD);
 /* Initiate *fcd data, must be called once, nbonds is the number 
  * of iatoms in the ilist of the idef struct.
  * When time averaging is used, the history is initialized in state,
  * unless it was read before from a checkpoint file.
+ * The implementation of distance restraints with -multi
+ * must differ according to whether REMD is active.
  */
 
 void calc_disres_R_6(const gmx_multisim_t *ms,
index 6e785fe840b923811366d1a2b2c03b5246edc5c2..87ff33ea657f2e1432d0e88c356e6c6f91d4f6d4 100644 (file)
@@ -111,6 +111,13 @@ gmx_bool change_dd_cutoff(t_commrec *cr,t_state *state,t_inputrec *ir,
  * then FALSE will be returned and the cut-off is not modified.
  */
 
+void change_dd_dlb_cutoff_limit(t_commrec *cr);
+/* Domain boundary changes due to the DD dynamic load balancing can limit
+ * the cut-off distance that can be set in change_dd_cutoff. This function
+ * limits the DLB such that using the currently set cut-off should still be
+ * possible after subsequently setting a shorter cut-off with change_dd_cutoff.
+ */
+
 void setup_dd_grid(FILE *fplog,gmx_domdec_t *dd);
 
 void dd_collect_vec(gmx_domdec_t *dd,
index bbd6e612cbdc3b63dfc8bcefbbc523d71afc266c..b256573aabd99502b58f1c070f2493a165d8a735 100644 (file)
@@ -63,6 +63,7 @@ void gmx_omp_nthreads_init(FILE *fplog, t_commrec *cr,
 int gmx_omp_nthreads_get(int mod);
 
 /*! Read the OMP_NUM_THREADS env. var. and check against the value set on the command line. */
-void gmx_omp_nthreads_read_env(int *nthreads_omp);
+void gmx_omp_nthreads_read_env(int *nthreads_omp,
+                               gmx_bool bIsSimMaster);
 
 #endif /* GMX_OMP_NTHREADS */
index 068e34960f7707ccdefe05822e59001f8315afa2..b2c96c46fe2de2f2068755964464abf90c9d60dc 100644 (file)
@@ -62,9 +62,6 @@ int do_full_memtest(int dev_id) FUNC_TERM_INT
 FUNC_QUALIFIER
 int do_timed_memtest(int dev_id, int time_limit) FUNC_TERM_INT
 
-FUNC_QUALIFIER
-gmx_bool is_gmx_openmm_supported_gpu(int dev_id, char *gpu_name) FUNC_TERM_INT
-
 FUNC_QUALIFIER
 int detect_cuda_gpus(gmx_gpu_info_t *gpu_info, char *err_str) FUNC_TERM_INT
 
index 8b9ed28563c02c7a8febea5cb18d41738c221ef0..5b73b885d3d91533811fb7aea155a613005b08b1 100644 (file)
@@ -60,13 +60,17 @@ void gmx_log_close(FILE *fp);
 /* Close the log file */
 
 void check_multi_int(FILE *log,const gmx_multisim_t *ms,
-                           int val,const char *name);
+                     int val,const char *name,
+                     gmx_bool bQuiet);
 void check_multi_large_int(FILE *log,const gmx_multisim_t *ms,
-                           gmx_large_int_t val,const char *name);
+                           gmx_large_int_t val,const char *name,
+                           gmx_bool bQuiet);
 /* Check if val is the same on all processors for a mdrun -multi run
  * The string name is used to print to the log file and in a fatal error
- * if the val's don't match.
+ * if the val's don't match. If bQuiet is true and the check passes,
+ * no output is written.
  */
+
 void init_multisystem(t_commrec *cr, int nsim, char **multidirs,
                       int nfile, const t_filenm fnm[], gmx_bool bParFn);
 /* Splits the communication into nsim separate simulations
index 3471fd8f644107b0045b639746fc8c34cb863cfb..8f9661d98888b963c7795076af6f7d241da3d37c 100644 (file)
@@ -53,6 +53,7 @@ extern "C" {
 /* forward declaration */
 typedef struct t_mde_delta_h_coll t_mde_delta_h_coll;
 
+
 /* This is the collection of energy averages collected during mdrun, and to 
    be written out to the .edr file. */
 typedef struct {
@@ -89,10 +90,25 @@ typedef struct {
   char   **print_grpnms;
 
   FILE   *fp_dhdl; /* the dhdl.xvg output file */
+  double *dE; /* energy components for dhdl.xvg output */
   t_mde_delta_h_coll *dhc; /* the delta U components (raw data + histogram) */
   real *temperatures;
 } t_mdebin;
 
+
+/* delta_h block type enum: the kinds of energies written out. */
+enum
+{
+    dhbtDH=0,    /* delta H BAR energy difference*/
+    dhbtDHDL=1,  /* dH/dlambda derivative */
+    dhbtEN,      /* System energy */
+    dhbtPV,      /* pV term */
+    dhbtEXPANDED, /* expanded ensemble statistics */
+    dhbtNR
+};
+
+
+
 t_mdebin *init_mdebin(ener_file_t fp_ene,
                              const gmx_mtop_t *mtop,
                              const t_inputrec *ir,
index 5914c054d2bdc0d40f2a56d7dca0018ec93db522..3c802d57f311bb1bf7cad063f2f64f45784a11ee 100644 (file)
@@ -140,9 +140,6 @@ typedef double gmx_integrator_t(FILE *log,t_commrec *cr,
 
 gmx_integrator_t do_md;
 
-gmx_integrator_t do_md_openmm;
-
-
 
 /* ROUTINES from minimize.c */
 
index 7b2e56aa2641f22fa2273c874b06d8a25f8c83b4..8ed17680aefc986dccb74a290d0b2c318d5873fd 100644 (file)
@@ -72,6 +72,7 @@ extern const char *gtypes[egcNR+1];
 extern const char *esimtemp_names[esimtempNR+1];
 extern const char *efep_names[efepNR+1];
 extern const char *efpt_names[efptNR+1];
+extern const char *efpt_singular_names[efptNR+1];
 extern const char *elamstats_names[elamstatsNR+1];
 extern const char *elmcmove_names[elmcmoveNR+1];
 extern const char *elmceq_names[elmceqNR+1];
index 179b669beea0fb51e17ba7633e31b53ddf47dc92..d450be34e84ab4c852be2c25019acabfd5bc8a8c 100644 (file)
@@ -54,6 +54,8 @@ static const char * const gpu_detect_res_str[] =
 typedef struct 
 {
     gmx_bool            bUserSet;       /* true if the GPUs in cuda_dev_use are manually provided by the user */
+    gmx_bool            bDevShare;      /* true if any of the devices is shared by
+                                           (t)MPI ranks, with auto-detection always FALSE */
 
     int                 ncuda_dev_use;  /* number of devices selected to be used */
     int                 *cuda_dev_use;  /* index of the devices selected to be used */
index a3d9c6fd7fd7c327eb62a2810ec4ee3124c6bddb..0a05ddff51ed165967b93ab141e01d2a00440c78 100644 (file)
@@ -130,12 +130,20 @@ typedef struct {
 
 typedef struct {
   int  nstdhdl;          /* The frequency for calculating dhdl           */
-  double init_lambda;    /* fractional value of lambda (usually will use init_fep_state, this will only be for slow growth, and for legacy free energy code)   */
+  double init_lambda;    /* fractional value of lambda (usually will use
+                            init_fep_state, this will only be for slow growth,
+                            and for legacy free energy code. Only has a
+                            valid value if positive)   */
   int init_fep_state;    /* the initial number of the state                   */
   double delta_lambda;  /* change of lambda per time step (fraction of (0.1) */
   gmx_bool bPrintEnergy; /* Whether to print the energy in the dhdl           */
   int  n_lambda;         /* The number of foreign lambda points               */
   double **all_lambda;   /* The array of all lambda values                    */
+  int lambda_neighbors;  /* The number of neighboring lambda states to
+                            calculate the energy for in up and down directions
+                            (-1 for all) */
+  int lambda_start_n;    /* The first lambda to calculate energies for */
+  int lambda_stop_n;     /* The last lambda +1 to calculate energies for */
   real sc_alpha;         /* free energy soft-core parameter                   */
   int  sc_power;         /* lambda power for soft-core interactions           */
   real sc_r_power;          /* r power for soft-core interactions                */
index 501c2743ccba94262b05f78361f973e0d73b533a..915b4de9fec54d48fc7f98dcbc41b35a352a83d0 100644 (file)
@@ -54,7 +54,7 @@ typedef struct
 {
     real f,fprev,x,xprev;  
     int iter_i;
-    gmx_bool bIterate;
+    gmx_bool bIterationActive;
     real allrelerr[MAXITERCONST+2];
     int num_close; /* number of "close" violations, caused by limited precision. */
 } gmx_iterate_t;
index 932a732377b50a25cce47dedd6798b047e094dd9..a867ba96b1506bedf68bd0cfe2c285cc7d2ab87f 100644 (file)
@@ -39,7 +39,6 @@
 #include "gromacs/legacyheaders/smalloc.h"
 
 #include "gromacs/linearalgebra/sparsematrix.h"
-
 #include "gmx_lapack.h"
 #include "gmx_arpack.h"
 
index 0a8c68b678ac53b117b74a7a58f2dee4e2b4964e..47c8031582a9ecb0b46c09e36132b5c83cc47bc8 100644 (file)
 #include <string.h>
 
 #include "gromacs/legacyheaders/types/simple.h"
-
 #include "gmx_arpack.h"
 #include "gmx_blas.h"
 #include "gmx_lapack.h"
-
 static void 
 F77_FUNC(dstqrb,DSTQRB)(int *      n, 
                         double *   d__, 
index 5b5fff88e7e54f559f5d5ca7847fc41f96db0346..d7b170b591469dca01a6de578520946fd79f1f3e 100644 (file)
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
-#ifndef F77_FUNC
-#define F77_FUNC(name,NAME) name ## _
-#endif
-
 #ifdef __cplusplus
 extern "C" {
 #endif
index f345d45a9a93045129aa56fc89ef4ef2966a58fa..e9ffbd72bd697535b314ddd4d3ded283aea6b21e 100644 (file)
@@ -57,9 +57,6 @@
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
-#ifndef F77_FUNC
-#define F77_FUNC(name,NAME) name ## _
-#endif
 
 /* Suppress Cygwin compiler warnings from using newlib version of
  * ctype.h */
index 548acf40da9ec458530dc8ff7fbe0be97790a7cd..db616395e84b078b4564f251da3f2751543b9c1c 100644 (file)
@@ -63,9 +63,6 @@
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
-#ifndef F77_FUNC
-#define F77_FUNC(name,NAME) name ## _
-#endif
 
 /* Suppress Cygwin compiler warnings from using newlib version of
  * ctype.h */
@@ -79,7 +76,6 @@ extern "C" {
 #if 0
 }
 #endif
-
 /* Double precision */
 
 void
index b0fe96ea04934c74952588f8ffdcd4dae964295e..1632690ebe01dd6e78482389744edc61459c3867 100644 (file)
@@ -900,13 +900,11 @@ void trotter_update(t_inputrec *ir,gmx_large_int_t step, gmx_ekindata_t *ekind,
 
     trotter_seq = trotter_seqlist[trotter_seqno];
 
-    /* signal we are returning if nothing is going to be done in this routine */
-    if ((trotter_seq[0] == etrtSKIPALL)  || !(bCouple))
+    if ((trotter_seq[0] == etrtSKIPALL) || (!bCouple))
     {
         return;
     }
-
-    dtc = ir->nsttcouple*ir->delta_t;
+    dtc = ir->nsttcouple*ir->delta_t;  /* This is OK for NPT, because nsttcouple == nstpcouple is enforcesd */
     opts = &(ir->opts); /* just for ease of referencing */
     ngtc = opts->ngtc;
     assert(ngtc>0);
index e834fec52d3ab4136d37729a7eb85b5f8f240a52..2cc197225168b48489a173ef51cfd552f575bfac 100644 (file)
@@ -266,6 +266,13 @@ typedef struct gmx_domdec_comm
     /* Effectively no NB cut-off limit with DLB for systems without PBC? */
     gmx_bool bVacDLBNoLimit;
 
+    /* With PME load balancing we set limits on DLB */
+    gmx_bool bPMELoadBalDLBLimits;
+    /* DLB needs to take into account that we want to allow this maximum
+     * cut-off (for PME load balancing), this could limit cell boundaries.
+     */
+    real PMELoadBal_max_cutoff;
+
     /* tric_dir is only stored here because dd_get_ns_ranges needs it */
     ivec tric_dir;
     /* box0 and box_size are required with dim's without pbc and -gcom */
@@ -2678,6 +2685,26 @@ static void clear_dd_indices(gmx_domdec_t *dd,int cg_start,int a_start)
     }
 }
 
+/* This function should be used for moving the domain boudaries during DLB,
+ * for obtaining the minimum cell size. It checks the initially set limit
+ * comm->cellsize_min, for bonded and initial non-bonded cut-offs,
+ * and, possibly, a longer cut-off limit set for PME load balancing.
+ */
+static real cellsize_min_dlb(gmx_domdec_comm_t *comm,int dim_ind,int dim)
+{
+    real cellsize_min;
+
+    cellsize_min = comm->cellsize_min[dim];
+
+    if (!comm->bVacDLBNoLimit && comm->bPMELoadBalDLBLimits)
+    {
+        cellsize_min = max(cellsize_min,
+                           comm->PMELoadBal_max_cutoff/comm->cd[dim_ind].np_dlb);
+    }
+
+    return cellsize_min;
+}
+
 static real grid_jump_limit(gmx_domdec_comm_t *comm,real cutoff,
                             int dim_ind)
 {
@@ -2692,6 +2719,10 @@ static real grid_jump_limit(gmx_domdec_comm_t *comm,real cutoff,
     grid_jump_limit = comm->cellsize_limit;
     if (!comm->bVacDLBNoLimit)
     {
+        if (comm->bPMELoadBalDLBLimits)
+        {
+            cutoff = max(cutoff,comm->PMELoadBal_max_cutoff);
+        }
         grid_jump_limit = max(grid_jump_limit,
                               cutoff/comm->cd[dim_ind].np);
     }
@@ -3352,7 +3383,7 @@ static void set_dd_cell_sizes_dlb_root(gmx_domdec_t *dd,
         }
     }
     
-    cellsize_limit_f  = comm->cellsize_min[dim]/ddbox->box_size[dim];
+    cellsize_limit_f  = cellsize_min_dlb(comm,d,dim)/ddbox->box_size[dim];
     cellsize_limit_f *= DD_CELL_MARGIN;
     dist_min_f_hard   = grid_jump_limit(comm,comm->cutoff,d)/ddbox->box_size[dim];
     dist_min_f        = dist_min_f_hard * DD_CELL_MARGIN;
@@ -5557,11 +5588,6 @@ void setup_dd_grid(FILE *fplog,gmx_domdec_t *dd)
         }
     }
     
-    if (DDMASTER(dd))
-    {
-        fprintf(stderr,"Making %dD domain decomposition %d x %d x %d\n",
-           dd->ndim,dd->nc[XX],dd->nc[YY],dd->nc[ZZ]);
-    }
     if (fplog)
     {
         fprintf(fplog,"\nMaking %dD domain decomposition grid %d x %d x %d, home cell index %d %d %d\n\n",
@@ -6466,6 +6492,7 @@ gmx_domdec_t *init_domain_decomposition(FILE *fplog,t_commrec *cr,
         fprintf(fplog,"Dynamic load balancing: %s\n",edlb_names[comm->eDLB]);
     }
     dd->bGridJump = comm->bDynLoadBal;
+    comm->bPMELoadBalDLBLimits = FALSE;
     
     if (comm->nstSortCG)
     {
@@ -6869,7 +6896,7 @@ static void turn_on_dlb(FILE *fplog,t_commrec *cr,gmx_large_int_t step)
     dd_warning(cr,fplog,"NOTE: Turning on dynamic load balancing\n");
     comm->bDynLoadBal = TRUE;
     dd->bGridJump = TRUE;
-    
+
     set_dlb_limits(dd);
 
     /* We can set the required cell size info here,
@@ -7252,8 +7279,9 @@ void set_dd_parameters(FILE *fplog,gmx_domdec_t *dd,real dlb_scale,
     dd->ga2la = ga2la_init(natoms_tot,vol_frac*natoms_tot);
 }
 
-gmx_bool change_dd_cutoff(t_commrec *cr,t_state *state,t_inputrec *ir,
-                          real cutoff_req)
+static gmx_bool test_dd_cutoff(t_commrec *cr,
+                               t_state *state,t_inputrec *ir,
+                               real cutoff_req)
 {
     gmx_domdec_t *dd;
     gmx_ddbox_t ddbox;
@@ -7318,11 +7346,37 @@ gmx_bool change_dd_cutoff(t_commrec *cr,t_state *state,t_inputrec *ir,
         }
     }
 
-    dd->comm->cutoff = cutoff_req;
-
     return TRUE;
 }
 
+gmx_bool change_dd_cutoff(t_commrec *cr,t_state *state,t_inputrec *ir,
+                          real cutoff_req)
+{
+    gmx_bool bCutoffAllowed;
+
+    bCutoffAllowed = test_dd_cutoff(cr,state,ir,cutoff_req);
+
+    if (bCutoffAllowed)
+    {
+        cr->dd->comm->cutoff = cutoff_req;
+    }
+
+    return bCutoffAllowed;
+}
+
+void change_dd_dlb_cutoff_limit(t_commrec *cr)
+{
+    gmx_domdec_comm_t *comm;
+
+    comm = cr->dd->comm;
+
+    /* Turn on the DLB limiting (might have been on already) */
+    comm->bPMELoadBalDLBLimits = TRUE;
+
+    /* Change the cut-off limit */
+    comm->PMELoadBal_max_cutoff = comm->cutoff;
+}
+
 static void merge_cg_buffers(int ncell,
                              gmx_domdec_comm_dim_t *cd, int pulse,
                              int  *ncg_cell,
index 8ed1a583a0c5ebc7c6febd83816b4d57c36691eb..9eb75af90711e5a2704f98e89b042b125be7d18e 100644 (file)
@@ -1524,61 +1524,18 @@ static void pick_nbnxn_kernel(FILE *fp,
                               const t_commrec *cr,
                               const gmx_hw_info_t *hwinfo,
                               gmx_bool use_cpu_acceleration,
-                              gmx_bool *bUseGPU,
+                              gmx_bool bUseGPU,
+                              gmx_bool bEmulateGPU,
                               const t_inputrec *ir,
                               int *kernel_type,
                               int *ewald_excl,
                               gmx_bool bDoNonbonded)
 {
-    gmx_bool bEmulateGPU, bGPU, bEmulateGPUEnvVarSet;
-    char gpu_err_str[STRLEN];
-
     assert(kernel_type);
 
     *kernel_type = nbnxnkNotSet;
     *ewald_excl  = ewaldexclTable;
 
-    bEmulateGPUEnvVarSet = (getenv("GMX_EMULATE_GPU") != NULL);
-
-    /* if bUseGPU == NULL we don't want a GPU (e.g. hybrid mode kernel selection) */
-    bGPU = ((bUseGPU != NULL) && hwinfo->bCanUseGPU);
-
-    /* Run GPU emulation mode if GMX_EMULATE_GPU is defined. We will
-     * automatically switch to emulation if non-bonded calculations are
-     * turned off via GMX_NO_NONBONDED - this is the simple and elegant
-     * way to turn off GPU initialization, data movement, and cleanup. */
-    bEmulateGPU = (bEmulateGPUEnvVarSet || (!bDoNonbonded && bGPU));
-
-    /* Enable GPU mode when GPUs are available or GPU emulation is requested.
-     * The latter is useful to assess the performance one can expect by adding
-     * GPU(s) to the machine. The conditional below allows this even if mdrun
-     * is compiled without GPU acceleration support.
-     * Note that such a GPU acceleration performance assessment should be
-     * carried out by setting the GMX_EMULATE_GPU and GMX_NO_NONBONDED env. vars
-     * (and freezing the system as otherwise it would explode). */
-    if (bGPU || bEmulateGPUEnvVarSet)
-    {
-        if (bEmulateGPU)
-        {
-            bGPU = FALSE;
-        }
-        else
-        {
-            /* Each PP node will use the intra-node id-th device from the
-             * list of detected/selected GPUs. */
-            if (!init_gpu(cr->rank_pp_intranode, gpu_err_str, &hwinfo->gpu_info))
-            {
-                /* At this point the init should never fail as we made sure that
-                 * we have all the GPUs we need. If it still does, we'll bail. */
-                gmx_fatal(FARGS, "On node %d failed to initialize GPU #%d: %s",
-                          cr->nodeid,
-                          get_gpu_device_id(&hwinfo->gpu_info, cr->rank_pp_intranode),
-                          gpu_err_str);
-            }
-        }
-        *bUseGPU = bGPU;
-    }
-
     if (bEmulateGPU)
     {
         *kernel_type = nbnxnk8x8x8_PlainC;
@@ -1588,7 +1545,7 @@ static void pick_nbnxn_kernel(FILE *fp,
             md_print_warn(cr, fp, "Emulating a GPU run on the CPU (slow)");
         }
     }
-    else if (bGPU)
+    else if (bUseGPU)
     {
         *kernel_type = nbnxnk8x8x8_CUDA;
     }
@@ -1615,6 +1572,55 @@ static void pick_nbnxn_kernel(FILE *fp,
     }
 }
 
+static void pick_nbnxn_resources(FILE *fp,
+                                 const t_commrec *cr,
+                                 const gmx_hw_info_t *hwinfo,
+                                 gmx_bool bDoNonbonded,
+                                 gmx_bool *bUseGPU,
+                                 gmx_bool *bEmulateGPU)
+{
+    gmx_bool bEmulateGPUEnvVarSet;
+    char gpu_err_str[STRLEN];
+
+    *bUseGPU = FALSE;
+
+    bEmulateGPUEnvVarSet = (getenv("GMX_EMULATE_GPU") != NULL);
+
+    /* Run GPU emulation mode if GMX_EMULATE_GPU is defined. Because
+     * GPUs (currently) only handle non-bonded calculations, we will
+     * automatically switch to emulation if non-bonded calculations are
+     * turned off via GMX_NO_NONBONDED - this is the simple and elegant
+     * way to turn off GPU initialization, data movement, and cleanup.
+     *
+     * GPU emulation can be useful to assess the performance one can expect by
+     * adding GPU(s) to the machine. The conditional below allows this even
+     * if mdrun is compiled without GPU acceleration support.
+     * Note that you should freezing the system as otherwise it will explode.
+     */
+    *bEmulateGPU = (bEmulateGPUEnvVarSet ||
+                    (!bDoNonbonded && hwinfo->bCanUseGPU));
+
+    /* Enable GPU mode when GPUs are available or no GPU emulation is requested.
+     */
+    if (hwinfo->bCanUseGPU && !(*bEmulateGPU))
+    {
+        /* Each PP node will use the intra-node id-th device from the
+         * list of detected/selected GPUs. */
+        if (!init_gpu(cr->rank_pp_intranode, gpu_err_str, &hwinfo->gpu_info))
+        {
+            /* At this point the init should never fail as we made sure that
+             * we have all the GPUs we need. If it still does, we'll bail. */
+            gmx_fatal(FARGS, "On node %d failed to initialize GPU #%d: %s",
+                      cr->nodeid,
+                      get_gpu_device_id(&hwinfo->gpu_info, cr->rank_pp_intranode),
+                      gpu_err_str);
+        }
+
+        /* Here we actually turn on hardware GPU acceleration */
+        *bUseGPU = TRUE;
+    }
+}
+
 gmx_bool uses_simple_tables(int cutoff_scheme,
                             nonbonded_verlet_t *nbv,
                             int group)
@@ -1797,13 +1803,18 @@ static void init_nb_verlet(FILE *fp,
     nonbonded_verlet_t *nbv;
     int  i;
     char *env;
-    gmx_bool bHybridGPURun = FALSE;
+    gmx_bool bEmulateGPU, bHybridGPURun = FALSE;
 
     nbnxn_alloc_t *nb_alloc;
     nbnxn_free_t  *nb_free;
 
     snew(nbv, 1);
 
+    pick_nbnxn_resources(fp, cr, fr->hwinfo,
+                         fr->bNonbonded,
+                         &nbv->bUseGPU,
+                         &bEmulateGPU);
+
     nbv->nbs = NULL;
 
     nbv->ngrp = (DOMAINDECOMP(cr) ? 2 : 1);
@@ -1816,7 +1827,7 @@ static void init_nb_verlet(FILE *fp,
         if (i == 0) /* local */
         {
             pick_nbnxn_kernel(fp, cr, fr->hwinfo, fr->use_cpu_acceleration,
-                              &nbv->bUseGPU,
+                              nbv->bUseGPU, bEmulateGPU,
                               ir,
                               &nbv->grp[i].kernel_type,
                               &nbv->grp[i].ewald_excl,
@@ -1828,7 +1839,7 @@ static void init_nb_verlet(FILE *fp,
             {
                 /* Use GPU for local, select a CPU kernel for non-local */
                 pick_nbnxn_kernel(fp, cr, fr->hwinfo, fr->use_cpu_acceleration,
-                                  NULL,
+                                  FALSE, FALSE,
                                   ir,
                                   &nbv->grp[i].kernel_type,
                                   &nbv->grp[i].ewald_excl,
@@ -2148,6 +2159,7 @@ void init_forcerec(FILE *fp,
             fr->bMolPBC = dd_bonded_molpbc(cr->dd,fr->ePBC);
         }
     }
+    fr->bGB = (ir->implicit_solvent == eisGBSA);
 
     fr->rc_scaling = ir->refcoord_scaling;
     copy_rvec(ir->posres_com,fr->posres_com);
@@ -2164,7 +2176,7 @@ void init_forcerec(FILE *fp,
     switch(fr->eeltype)
     {
         case eelCUT:
-            fr->nbkernel_elec_interaction = GMX_NBKERNEL_ELEC_COULOMB;
+            fr->nbkernel_elec_interaction = (fr->bGB) ? GMX_NBKERNEL_ELEC_GENERALIZEDBORN : GMX_NBKERNEL_ELEC_COULOMB;
             break;
 
         case eelRF:
@@ -2416,7 +2428,6 @@ void init_forcerec(FILE *fp,
         set_bham_b_max(fp,fr,mtop);
     }
 
-    fr->bGB = (ir->implicit_solvent == eisGBSA);
        fr->gb_epsilon_solvent = ir->gb_epsilon_solvent;
 
     /* Copy the GBSA data (radius, volume and surftens for each
index 4a0905cbe3e355f24e9186c616c06993bb2d5540..16dc7f5ad8d082eabd666ef8a5eeae451c85c3c6 100644 (file)
@@ -495,22 +495,22 @@ calc_gb_rad_still(t_commrec *cr, t_forcerec *fr,int natoms, gmx_localtop_t *top,
     real rinv,idr2,idr6,vaj,dccf,cosq,sinq,prod,gpi2;
     real factor;
     real vai, prod_ai, icf4,icf6;
-    
+
     factor  = 0.5*ONE_4PI_EPS0;
     n       = 0;
-    
+
     for(i=0;i<born->nr;i++)
     {
         born->gpol_still_work[i]=0;
     }
-     
-       for(i=0;i<nl->nri;i++ )
+
+    for(i=0;i<nl->nri;i++ )
     {
         ai      = nl->iinr[i];
-        
+
         nj0     = nl->jindex[i];            
         nj1     = nl->jindex[i+1];
-    
+
         /* Load shifts for this list */
         shift   = nl->shift[i];
         shX     = fr->shift_vec[shift][0];
@@ -527,8 +527,8 @@ calc_gb_rad_still(t_commrec *cr, t_forcerec *fr,int natoms, gmx_localtop_t *top,
         ix1     = shX + x[ai][0];
         iy1     = shY + x[ai][1];
         iz1     = shZ + x[ai][2];
-                        
-        for(k=nj0;k<nj1;k++)
+
+        for(k=nj0;k<nj1 && nl->jjnr[k]>=0;k++)
         {
             aj    = nl->jjnr[k];
             jx1   = x[aj][0];
@@ -552,7 +552,7 @@ calc_gb_rad_still(t_commrec *cr, t_forcerec *fr,int natoms, gmx_localtop_t *top,
             ratio = dr2 / (rvdw * rvdw);
             vaj   = born->vsolv[aj];
             
-            if(ratio>STILL_P5INV) 
+            if(ratio>STILL_P5INV)
             {
                 ccf=1.0;
                 dccf=0.0;
@@ -570,7 +570,6 @@ calc_gb_rad_still(t_commrec *cr, t_forcerec *fr,int natoms, gmx_localtop_t *top,
             prod          = STILL_P4*vaj;
             icf4          = ccf*idr4;
             icf6          = (4*ccf-dccf)*idr6;
-
             born->gpol_still_work[aj] += prod_ai*icf4;
             gpi             = gpi+prod*icf4;
             
@@ -596,7 +595,6 @@ calc_gb_rad_still(t_commrec *cr, t_forcerec *fr,int natoms, gmx_localtop_t *top,
     {
                if(born->use[i] != 0)
         {
-               
             gpi  = born->gpol[i]+born->gpol_still_work[i];
             gpi2 = gpi * gpi;
             born->bRad[i]   = factor*gmx_invsqrt(gpi2);
@@ -670,7 +668,7 @@ calc_gb_rad_hct(t_commrec *cr,t_forcerec *fr,int natoms, gmx_localtop_t *top,
         
         sum_ai  = 0;
         
-        for(k=nj0;k<nj1;k++)
+        for(k=nj0;k<nj1 && nl->jjnr[k]>=0;k++)
         {
             aj    = nl->jjnr[k];
             
@@ -890,7 +888,7 @@ calc_gb_rad_obc(t_commrec *cr, t_forcerec *fr, int natoms, gmx_localtop_t *top,
         
         sum_ai   = 0;
         
-        for(k=nj0;k<nj1;k++)
+        for(k=nj0;k<nj1 && nl->jjnr[k]>=0;k++)
         {
             aj    = nl->jjnr[k];
             
@@ -1069,7 +1067,7 @@ int calc_gb_rad(t_commrec *cr, t_forcerec *fr, t_inputrec *ir,gmx_localtop_t *to
     real *p;
     int   cnt;
     int ndadx;
-
+    
     if(fr->bAllvsAll && fr->dadx==NULL)
     {
         /* We might need up to 8 atoms of padding before and after, 
@@ -1257,7 +1255,7 @@ int calc_gb_rad(t_commrec *cr, t_forcerec *fr, t_inputrec *ir,gmx_localtop_t *to
     switch(ir->gb_algorithm)
     {
         case egbSTILL:
-            calc_gb_rad_still(cr,fr,born->nr,top,atype,x,nl,born,md); 
+            calc_gb_rad_still(cr,fr,born->nr,top,atype,x,nl,born,md);
             break;
         case egbHCT:
             calc_gb_rad_hct(cr,fr,born->nr,top,atype,x,nl,born,md); 
@@ -1570,7 +1568,7 @@ real calc_gb_chainrule(int natoms, t_nblist *nl, real *dadx, real *dvda, rvec x[
         
         rbai = rb[ai];
         
-        for(k=nj0;k<nj1;k++)
+        for(k=nj0;k<nj1 && nl->jjnr[k]>=0;k++)
         {
             aj = nl->jjnr[k];
             
index 33851e0bd310b978555137e61006b4e6dd6bb7df..53b8439c03b93422c86b8c34067137020209c77a 100644 (file)
 /* maximum length of cyclic traps to check, emerging from limited numerical precision  */
 #define CYCLEMAX            20
 
-void gmx_iterate_init(gmx_iterate_t *iterate,gmx_bool bIterate)
+void gmx_iterate_init(gmx_iterate_t *iterate,gmx_bool bSetIterationActive)
 {
     int i;
 
     iterate->iter_i = 0;
-    iterate->bIterate = bIterate;
+    iterate->bIterationActive = bSetIterationActive;
     iterate->num_close = 0;
     for (i=0;i<MAXITERCONST+2;i++) 
     {
@@ -164,7 +164,7 @@ gmx_bool done_iterating(const t_commrec *cr,FILE *fplog, int nsteps, gmx_iterate
         
         if ((relerr < CONVERGEITER) || (err < CONVERGEITER) || (fom==0) || ((iterate->x == iterate->xprev) && iterate->iter_i > 1))
         {
-            iterate->bIterate = FALSE;
+            iterate->bIterationActive = FALSE;
             if (debug) 
             {
                 fprintf(debug,"Iterating NPT constraints: CONVERGED\n");
@@ -194,6 +194,7 @@ gmx_bool done_iterating(const t_commrec *cr,FILE *fplog, int nsteps, gmx_iterate
                        Better to give up convergence here than have the simulation die.
                     */
                     iterate->num_close++;
+                    iterate->bIterationActive = FALSE;
                     return TRUE;
                 } 
                 else 
@@ -205,6 +206,7 @@ gmx_bool done_iterating(const t_commrec *cr,FILE *fplog, int nsteps, gmx_iterate
                     {
                         md_print_warn(cr,fplog,"Slight numerical convergence deviation with NPT at step %d, relative error only %10.5g, likely not a problem, continuing\n",nsteps,relerr);
                         iterate->num_close++;
+                        iterate->bIterationActive = FALSE;
                         return TRUE;
                         /* if more than a few, check the total fraction.  If too high, die. */
                     } else if (iterate->num_close/(double)nsteps > FRACTION_CLOSE) {
index aa6cfad96f77e7aefa10760a013bd47e5c1e7a5b..1f77c242d1b11d0c5fd69199464c81405be0996a 100644 (file)
@@ -180,6 +180,9 @@ t_mdebin *init_mdebin(ener_file_t fp_ene,
         md->bEInd[i]=FALSE;
     }
 
+    /* Even though the OpenMM build has moved to contrib, it's not
+     * practical to move/remove this code fragment, because of the
+     * fundamental mess that is the GROMACS library structure. */
 #ifndef GMX_OPENMM
     for(i=0; i<F_NRE; i++)
     {
@@ -585,10 +588,12 @@ t_mdebin *init_mdebin(ener_file_t fp_ene,
             mde_delta_h_coll_init(md->dhc, ir);
         }
         md->fp_dhdl = NULL;
+        snew(md->dE,ir->fepvals->n_lambda);
     }
     else
     {
         md->fp_dhdl = fp_dhdl;
+        snew(md->dE,ir->fepvals->n_lambda);
     }
     if (ir->bSimTemp) {
         int i;
@@ -601,6 +606,66 @@ t_mdebin *init_mdebin(ener_file_t fp_ene,
     return md;
 }
 
+/* print a lambda vector to a string
+   fep = the inputrec's FEP input data
+   i = the index of the lambda vector
+   get_native_lambda = whether to print the native lambda
+   get_names = whether to print the names rather than the values
+   str = the pre-allocated string buffer to print to. */
+static void print_lambda_vector(t_lambda *fep, int i,
+                                gmx_bool get_native_lambda, gmx_bool get_names,
+                                char *str)
+{
+    size_t nps=0, np;
+    int j,k=0;
+    int Nsep=0;
+
+    for (j=0;j<efptNR;j++)
+    {
+        if (fep->separate_dvdl[j])
+            Nsep ++;
+    }
+    str[0]=0; /* reset the string */
+    if (Nsep > 1)
+    {
+        str += sprintf(str, "("); /* set the opening parenthesis*/
+    }
+    for (j=0;j<efptNR;j++)
+    {
+        if (fep->separate_dvdl[j])
+        {
+            double lam;
+            if (!get_names)
+            {
+                if (get_native_lambda && fep->init_lambda >= 0)
+                {
+                    str += sprintf(str,"%.4f", fep->init_lambda);
+                }
+                else
+                {
+                    str += sprintf(str,"%.4f", fep->all_lambda[j][i]);
+                }
+            }
+            else
+            {
+                str += sprintf(str,"%s", efpt_singular_names[j]);
+            }
+            /* print comma for the next item */
+            if (k<Nsep-1)
+            {
+                str += sprintf(str,", ");
+            }
+            k++;
+        }
+    }
+    if (Nsep > 1)
+    {
+        /* and add the closing parenthesis */
+        str += sprintf(str, ")");
+    }
+}
+
+
 extern FILE *open_dhdl(const char *filename,const t_inputrec *ir,
                        const output_env_t oenv)
 {
@@ -609,17 +674,26 @@ extern FILE *open_dhdl(const char *filename,const t_inputrec *ir,
         *lambdastate="\\lambda state",*remain="remaining";
     char title[STRLEN],label_x[STRLEN],label_y[STRLEN];
     int  i,np,nps,nsets,nsets_de,nsetsbegin;
-    t_lambda *fep;
+    int n_lambda_terms=0;
+    t_lambda *fep=ir->fepvals; /* for simplicity */
+    t_expanded *expand=ir->expandedvals;
     char **setname;
-    char buf[STRLEN];
+    char buf[STRLEN], lambda_vec_str[STRLEN], lambda_name_str[STRLEN];
     int bufplace=0;
 
     int nsets_dhdl = 0;
     int s = 0;
     int nsetsextend;
+    gmx_bool write_pV = FALSE;
 
-    /* for simplicity */
-    fep = ir->fepvals;
+    /* count the number of different lambda terms */
+    for (i=0;i<efptNR;i++)
+    {
+        if (fep->separate_dvdl[i])
+        {
+            n_lambda_terms++;
+        }
+    }
 
     if (fep->n_lambda == 0)
     {
@@ -645,30 +719,36 @@ extern FILE *open_dhdl(const char *filename,const t_inputrec *ir,
     }
     if (ir->efep != efepSLOWGROWTH)
     {
-        if (fep->n_lambda == 0)
+        if ( (fep->init_lambda >= 0)  && (n_lambda_terms == 1 ))
         {
-            sprintf(&(buf[bufplace]),"%s = %g",
-                    lambda,fep->init_lambda);
+            /* compatibility output */
+            sprintf(&(buf[bufplace]),"%s = %.4f", lambda,fep->init_lambda);
         }
         else
         {
-            sprintf(&(buf[bufplace]),"%s = %d",
-                    lambdastate,fep->init_fep_state);
+            print_lambda_vector(fep, fep->init_fep_state, TRUE, FALSE,
+                                lambda_vec_str);
+            print_lambda_vector(fep, fep->init_fep_state, TRUE, TRUE,
+                                lambda_name_str);
+            sprintf(&(buf[bufplace]),"%s %d: %s = %s",
+                    lambdastate,fep->init_fep_state,
+                    lambda_name_str, lambda_vec_str);
         }
     }
     xvgr_subtitle(fp,buf,oenv);
 
-    for (i=0;i<efptNR;i++)
+
+    nsets_dhdl=0;
+    if (fep->dhdl_derivatives == edhdlderivativesYES)
     {
-        if (fep->separate_dvdl[i]) {nsets_dhdl++;}
+        nsets_dhdl = n_lambda_terms;
     }
-
     /* count the number of delta_g states */
-    nsets_de = fep->n_lambda;
+    nsets_de = fep->lambda_stop_n - fep->lambda_start_n;
 
     nsets = nsets_dhdl + nsets_de; /* dhdl + fep differences */
 
-    if (fep->n_lambda>0 && ir->bExpanded)
+    if (fep->n_lambda>0 && (expand->elmcmove > elmcmoveNO))
     {
         nsets += 1;   /*add fep state for expanded ensemble */
     }
@@ -679,13 +759,18 @@ extern FILE *open_dhdl(const char *filename,const t_inputrec *ir,
     }
 
     nsetsextend = nsets;
-    if ((ir->epc!=epcNO) && (fep->n_lambda>0))
+    if ((ir->epc!=epcNO) && (fep->n_lambda>0) && (fep->init_lambda < 0))
     {
-        nsetsextend += 1; /* for PV term, other terms possible if required for the reduced potential (only needed with foreign lambda) */
+        nsetsextend += 1; /* for PV term, other terms possible if required for
+                             the reduced potential (only needed with foreign
+                             lambda, and only output when init_lambda is not
+                             set in order to maintain compatibility of the
+                             dhdl.xvg file) */
+        write_pV = TRUE;
     }
     snew(setname,nsetsextend);
 
-    if (ir->bExpanded)
+    if (expand->elmcmove > elmcmoveNO)
     {
         /* state for the fep_vals, if we have alchemical sampling */
         sprintf(buf,"%s","Thermodynamic state");
@@ -700,12 +785,30 @@ extern FILE *open_dhdl(const char *filename,const t_inputrec *ir,
         s+=1;
     }
 
-    for (i=0;i<efptNR;i++)
+    if (fep->dhdl_derivatives == edhdlderivativesYES)
     {
-        if (fep->separate_dvdl[i]) {
-            sprintf(buf,"%s (%s)",dhdl,efpt_names[i]);
-            setname[s] = strdup(buf);
-            s+=1;
+        for (i=0;i<efptNR;i++)
+        {
+            if (fep->separate_dvdl[i]) {
+
+                if ( (fep->init_lambda >= 0)  && (n_lambda_terms == 1 ))
+                {
+                    /* compatibility output */
+                    sprintf(buf,"%s %s %.4f",dhdl,lambda, fep->init_lambda);
+                }
+                else
+                {
+                    double lam=fep->init_lambda;
+                    if (fep->init_lambda < 0)
+                    {
+                        lam=fep->all_lambda[i][fep->init_fep_state];
+                    }
+                    sprintf(buf,"%s %s = %.4f",dhdl, efpt_singular_names[i],
+                            lam);
+                }
+                setname[s] = strdup(buf);
+                s+=1;
+            }
         }
     }
 
@@ -715,7 +818,7 @@ extern FILE *open_dhdl(const char *filename,const t_inputrec *ir,
          * from this xvg legend.
          */
 
-        if (ir->bExpanded) {
+        if (expand->elmcmove > elmcmoveNO) {
             nsetsbegin = 1;  /* for including the expanded ensemble */
         } else {
             nsetsbegin = 0;
@@ -727,31 +830,33 @@ extern FILE *open_dhdl(const char *filename,const t_inputrec *ir,
         }
         nsetsbegin += nsets_dhdl;
 
-        for(s=nsetsbegin; s<nsets; s++)
+        for(i=fep->lambda_start_n; i<fep->lambda_stop_n; i++)
         {
-            nps = sprintf(buf,"%s %s (",deltag,lambda);
-            for (i=0;i<efptNR;i++)
+            print_lambda_vector(fep, i, FALSE, FALSE, lambda_vec_str);
+            if ( (fep->init_lambda >= 0)  && (n_lambda_terms == 1 ))
             {
-                if (fep->separate_dvdl[i])
-                {
-                    np = sprintf(&buf[nps],"%g,",fep->all_lambda[i][s-(nsetsbegin)]);
-                    nps += np;
-                }
+                /* for compatible dhdl.xvg files */
+                nps = sprintf(buf,"%s %s %s",deltag,lambda, lambda_vec_str);
             }
-            if (ir->bSimTemp)
+            else
             {
-                /* print the temperature for this state if doing simulated annealing */
-                sprintf(&buf[nps],"T = %g (%s))",ir->simtempvals->temperatures[s-(nsetsbegin)],unit_temp_K);
+                nps = sprintf(buf,"%s %s to %s",deltag,lambda, lambda_vec_str);
             }
-            else
+
+            if (ir->bSimTemp)
             {
-                sprintf(&buf[nps-1],")");  /* -1 to overwrite the last comma */
+                /* print the temperature for this state if doing simulated annealing */
+                sprintf(&buf[nps],"T = %g (%s)",
+                        ir->simtempvals->temperatures[s-(nsetsbegin)],
+                        unit_temp_K);
             }
             setname[s] = strdup(buf);
+            s++;
         }
-        if (ir->epc!=epcNO) {
+        if (write_pV) {
             np = sprintf(buf,"pV (%s)",unit_energy);
-            setname[nsetsextend-1] = strdup(buf);  /* the first entry after nsets */
+            setname[nsetsextend-1] = strdup(buf);  /* the first entry after
+                                                      nsets */
         }
 
         xvgr_legend(fp,nsetsextend,(const char **)setname,oenv);
@@ -801,7 +906,6 @@ void upd_mdebin(t_mdebin *md,
     real   eee[egNR];
     real   ecopy[F_NRE];
     double store_dhdl[efptNR];
-    double *dE=NULL;
     real   store_energy=0;
     real   tmp;
 
@@ -988,83 +1092,86 @@ void upd_mdebin(t_mdebin *md,
     ebin_increase_count(md->ebin,bSum);
 
     /* BAR + thermodynamic integration values */
-    if ((md->fp_dhdl || md->dhc) && bDoDHDL && (enerd->n_lambda > 0))
+    if ((md->fp_dhdl || md->dhc) && bDoDHDL)
     {
-        snew(dE,enerd->n_lambda-1);
         for(i=0; i<enerd->n_lambda-1; i++) {
-            dE[i] = enerd->enerpart_lambda[i+1]-enerd->enerpart_lambda[0];  /* zero for simulated tempering */
+            /* zero for simulated tempering */
+            md->dE[i] = enerd->enerpart_lambda[i+1]-enerd->enerpart_lambda[0];
             if (md->temperatures!=NULL)
             {
                 /* MRS: is this right, given the way we have defined the exchange probabilities? */
                 /* is this even useful to have at all? */
-                dE[i] += (md->temperatures[i]/md->temperatures[state->fep_state]-1.0)*enerd->term[F_EKIN];
+                md->dE[i] += (md->temperatures[i]/
+                          md->temperatures[state->fep_state]-1.0)*
+                            enerd->term[F_EKIN];
             }
         }
-    }
-
-    if (md->fp_dhdl && bDoDHDL)
-    {
-        fprintf(md->fp_dhdl,"%.4f",time);
-        /* the current free energy state */
 
-        /* print the current state if we are doing expanded ensemble */
-        if (expand->elmcmove > elmcmoveNO) {
-            fprintf(md->fp_dhdl," %4d",state->fep_state);
-        }
-        /* total energy (for if the temperature changes */
-        if (fep->bPrintEnergy)
+        if (md->fp_dhdl)
         {
-            store_energy = enerd->term[F_ETOT];
-            fprintf(md->fp_dhdl," %#.8g",store_energy);
-        }
+            fprintf(md->fp_dhdl,"%.4f",time);
+            /* the current free energy state */
 
-        for (i=0;i<efptNR;i++)
-        {
-            if (fep->separate_dvdl[i])
+            /* print the current state if we are doing expanded ensemble */
+            if (expand->elmcmove > elmcmoveNO) {
+                fprintf(md->fp_dhdl," %4d",state->fep_state);
+            }
+            /* total energy (for if the temperature changes */
+            if (fep->bPrintEnergy)
             {
-                fprintf(md->fp_dhdl," %#.8g",enerd->term[F_DVDL+i]); /* assumes F_DVDL is first */
+                store_energy = enerd->term[F_ETOT];
+                fprintf(md->fp_dhdl," %#.8g",store_energy);
             }
-        }
-        for(i=1; i<enerd->n_lambda; i++)
-        {
-            fprintf(md->fp_dhdl," %#.8g",dE[i-1]);
 
+            if (fep->dhdl_derivatives == edhdlderivativesYES)
+            {
+                for (i=0;i<efptNR;i++)
+                {
+                    if (fep->separate_dvdl[i])
+                    {
+                        /* assumes F_DVDL is first */
+                        fprintf(md->fp_dhdl," %#.8g",enerd->term[F_DVDL+i]);
+                    }
+                }
+            }
+            for(i=fep->lambda_start_n;i<fep->lambda_stop_n;i++)
+            {
+                fprintf(md->fp_dhdl," %#.8g",md->dE[i]);
+            }
+            if ((md->epc!=epcNO)  && 
+                (enerd->n_lambda > 0) &&
+                (fep->init_lambda<0))
+            {
+                fprintf(md->fp_dhdl," %#.8g",pv);  /* PV term only needed when
+                                                      there are alternate state
+                                                      lambda and we're not in
+                                                      compatibility mode */
+            }
+            fprintf(md->fp_dhdl,"\n");
+            /* and the binary free energy output */
         }
-        if ((md->epc!=epcNO)  && (enerd->n_lambda > 0))
-        {
-            fprintf(md->fp_dhdl," %#.8g",pv);   /* PV term only needed when there are alternate state lambda */
-        }
-        fprintf(md->fp_dhdl,"\n");
-        /* and the binary free energy output */
-    }
-    if (md->dhc && bDoDHDL)
-    {
-        int idhdl = 0;
-        for (i=0;i<efptNR;i++)
+        if (md->dhc && bDoDHDL)
         {
-            if (fep->separate_dvdl[i])
+            int idhdl = 0;
+            for (i=0;i<efptNR;i++)
             {
-                store_dhdl[idhdl] = enerd->term[F_DVDL+i]; /* assumes F_DVDL is first */
-                idhdl+=1;
+                if (fep->separate_dvdl[i])
+                {
+                    /* assumes F_DVDL is first */
+                    store_dhdl[idhdl] = enerd->term[F_DVDL+i];
+                    idhdl+=1;
+                }
             }
+            store_energy = enerd->term[F_ETOT];
+            /* store_dh is dE */
+            mde_delta_h_coll_add_dh(md->dhc,
+                                    (double)state->fep_state,
+                                    store_energy,
+                                    pv,
+                                    store_dhdl,
+                                    md->dE + fep->lambda_start_n,
+                                    time);
         }
-        /* store_dh is dE */
-        mde_delta_h_coll_add_dh(md->dhc,
-                                (double)state->fep_state,
-                                store_energy,
-                                pv,
-                                (expand->elamstats>elamstatsNO),
-                                (fep->bPrintEnergy),
-                                (md->epc!=epcNO),
-                                idhdl,
-                                fep->n_lambda,
-                                store_dhdl,
-                                dE,
-                                time);
-    }
-    if ((md->fp_dhdl || md->dhc) && bDoDHDL && (enerd->n_lambda >0))
-    {
-        sfree(dE);
     }
 }
 
index f496f68b30e41d9d32a645beb5fed8c286ac4051..7bd56bd9adec8b543a72215b0e617f70ca864904 100644 (file)
@@ -58,10 +58,26 @@ static void mde_delta_h_reset(t_mde_delta_h *dh)
 
 /* initialize the delta_h list */
 static void mde_delta_h_init(t_mde_delta_h *dh, int nbins,
-                             double dx, unsigned int  ndhmax)
+                             double dx, unsigned int  ndhmax,
+                             int type, int derivative, int nlambda,
+                             double *lambda)
 {
     int i;
 
+    dh->type=type;
+    dh->derivative=derivative;
+    dh->lambda=lambda;
+    dh->nlambda=nlambda;
+
+    snew(dh->lambda, nlambda);
+    for(i=0;i<nlambda;i++)
+    {
+        dh->lambda[i] = lambda[i];
+    }
+
+
+    snew(dh->subblock_meta_d, dh->nlambda+1);
+
     dh->ndhmax=ndhmax+2;
     for(i=0;i<2;i++)
     {
@@ -187,32 +203,42 @@ void mde_delta_h_handle_block(t_mde_delta_h *dh, t_enxblock *blk)
     /* first check which type we should use: histogram or raw data */
     if (dh->nhist == 0)
     {
-        unsigned int i;
+        int i;
 
         /* We write raw data.
-           Raw data consists of 3 subblocks: a block with the
-           the foreign lambda, and the data itself */
+           Raw data consists of 3 subblocks: an int metadata block
+           with type and derivative index, a foreign lambda block
+           and and the data itself */
         add_subblocks_enxblock(blk, 3);
 
         blk->id=enxDH;
 
         /* subblock 1 */
-        dh->subblock_i[0]=dh->derivative ? 1 : 0; /* derivative type */
-        blk->sub[0].nr=1;
+        dh->subblock_meta_i[0]=dh->type; /* block data type */
+        dh->subblock_meta_i[1]=dh->derivative; /* derivative direction if
+                                                  applicable (in indices
+                                                  starting from first coord in
+                                                  the main delta_h_coll) */
+        blk->sub[0].nr=2;
         blk->sub[0].type=xdr_datatype_int;
-        blk->sub[0].ival=dh->subblock_i;
+        blk->sub[0].ival=dh->subblock_meta_i;
 
         /* subblock 2 */
-        dh->subblock_d[0]=dh->lambda;
-        blk->sub[1].nr=1;
+        for(i=0;i<dh->nlambda;i++)
+        {
+            dh->subblock_meta_d[i]=dh->lambda[i];
+        }
+        blk->sub[1].nr=dh->nlambda;
         blk->sub[1].type=xdr_datatype_double;
-        blk->sub[1].dval=dh->subblock_d;
+        blk->sub[1].dval=dh->subblock_meta_d;
 
         /* subblock 3 */
         /* check if there's actual data to be written. */
         /*if (dh->ndh > 1)*/
         if (dh->ndh > 0)
         {
+            unsigned int i;
+
             blk->sub[2].nr=dh->ndh;
 /* For F@H for now. */
 #undef GMX_DOUBLE
@@ -237,15 +263,17 @@ void mde_delta_h_handle_block(t_mde_delta_h *dh, t_enxblock *blk)
             blk->sub[2].fval=NULL;
 #else
             blk->sub[2].type=xdr_datatype_double;
-#endif
             blk->sub[2].dval=NULL;
+#endif
         }
     }
     else
     {
         int nhist_written=0;
         int i;
+        int k;
 
+        /* TODO histogram metadata */
         /* check if there's actual data to be written. */
         if (dh->ndh > 1)
         {
@@ -276,22 +304,37 @@ void mde_delta_h_handle_block(t_mde_delta_h *dh, t_enxblock *blk)
         add_subblocks_enxblock(blk, nhist_written+2);
         blk->id=enxDHHIST;
 
-        /* subblock 1: the foreign lambda value + the histogram spacing */
-        dh->subblock_d[0]=dh->lambda;
-        dh->subblock_d[1]=dh->dx;
-        blk->sub[0].nr=2;
+        /* subblock 1: the lambda value + the histogram spacing */
+        if (dh->nlambda == 1)
+        {
+            /* for backward compatibility */
+            dh->subblock_meta_d[0]=dh->lambda[0];
+        }
+        else
+        {
+            dh->subblock_meta_d[0]=-1;
+            for(i=0;i<dh->nlambda;i++)
+            {
+                dh->subblock_meta_d[2+i]=dh->lambda[i];
+            }
+        }
+        dh->subblock_meta_d[1]=dh->dx;
+        blk->sub[0].nr = 2+ ((dh->nlambda>1) ? dh->nlambda : 0);
         blk->sub[0].type=xdr_datatype_double;
-        blk->sub[0].dval=dh->subblock_d;
+        blk->sub[0].dval=dh->subblock_meta_d;
 
         /* subblock 2: the starting point(s) as a long integer */
-        dh->subblock_l[0]=nhist_written;
-        dh->subblock_l[1]=dh->derivative ? 1 : 0;
+        dh->subblock_meta_l[0]=nhist_written;
+        dh->subblock_meta_l[1]=dh->type; /*dh->derivative ? 1 : 0;*/
+        k=2;
         for(i=0;i<nhist_written;i++)
-            dh->subblock_l[2+i]=dh->x0[i];
+            dh->subblock_meta_l[k++]=dh->x0[i];
+        /* append the derivative data */
+        dh->subblock_meta_l[k++]=dh->derivative;
 
-        blk->sub[1].nr=nhist_written+2;
+        blk->sub[1].nr=nhist_written+3;
         blk->sub[1].type=xdr_datatype_large_int;
-        blk->sub[1].lval=dh->subblock_l;
+        blk->sub[1].lval=dh->subblock_meta_l;
 
         /* subblock 3 + 4 : the histogram data */
         for(i=0;i<nhist_written;i++)
@@ -307,53 +350,203 @@ void mde_delta_h_handle_block(t_mde_delta_h *dh, t_enxblock *blk)
 /* initialize the collection*/
 void mde_delta_h_coll_init(t_mde_delta_h_coll *dhc, const t_inputrec *ir)
 {
-    int i;
+    int i,j,n;
     double lambda;
+    double *lambda_vec;
     int ndhmax=ir->nstenergy/ir->nstcalcenergy;
+    t_lambda *fep=ir->fepvals;
 
     dhc->temperature=ir->opts.ref_t[0];  /* only store system temperature */
     dhc->start_time=0.;
     dhc->delta_time=ir->delta_t*ir->fepvals->nstdhdl;
     dhc->start_time_set=FALSE;
 
-    /* for continuous change of lambda values */
+    /* this is the compatibility lambda value. If it is >=0, it is valid,
+       and there is either an old-style lambda or a slow growth simulation. */
     dhc->start_lambda=ir->fepvals->init_lambda;
+    /* for continuous change of lambda values */
     dhc->delta_lambda=ir->fepvals->delta_lambda*ir->fepvals->nstdhdl;
 
-    /* total number of raw data points in the sample */
-    dhc->ndh = 0;
-
-    /* include one more for the specification of the state, by lambda or fep_state, store as double for now*/
-    if (ir->expandedvals->elamstats > elamstatsNO) {
-        dhc->ndh +=1;
+    if (dhc->start_lambda < 0)
+    {
+        /* create the native lambda vectors */
+        dhc->lambda_index=fep->init_fep_state;
+        dhc->n_lambda_vec=0;
+        for(i=0;i<efptNR;i++)
+        {
+            if (fep->separate_dvdl[i])
+            {
+                dhc->n_lambda_vec++;
+            }
+        }
+        snew(dhc->native_lambda_vec, dhc->n_lambda_vec);
+        snew(dhc->native_lambda_components, dhc->n_lambda_vec);
+        j=0;
+        for(i=0;i<efptNR;i++)
+        {
+            if (fep->separate_dvdl[i])
+            {
+                dhc->native_lambda_components[j]=i;
+                if (fep->init_fep_state >=0 &&
+                    fep->init_fep_state < fep->n_lambda)
+                {
+                    dhc->native_lambda_vec[j]=
+                                fep->all_lambda[i][fep->init_fep_state];
+                }
+                else
+                {
+                    dhc->native_lambda_vec[j]=-1;
+                }
+                j++;
+            }
+        }
     }
-
-    /* whether to print energies */
-    if (ir->fepvals->bPrintEnergy) {
-        dhc->ndh += 1;
+    else
+    {
+        /* don't allocate the meta-data subblocks for lambda vectors */
+        dhc->native_lambda_vec=NULL;
+        dhc->n_lambda_vec=0;
+        dhc->native_lambda_components=0;
+        dhc->lambda_index=-1;
     }
+    /* allocate metadata subblocks */
+    snew(dhc->subblock_d, 5 + dhc->n_lambda_vec);
+    snew(dhc->subblock_i, 1 + dhc->n_lambda_vec);
+
+    /* now decide which data to write out */
+    dhc->nlambda=0;
+    dhc->ndhdl=0;
+    dhc->dh_expanded=NULL;
+    dhc->dh_energy=NULL;
+    dhc->dh_pv=NULL;
+
+    /* total number of raw data point collections in the sample */
+    dhc->ndh = 0;
 
-    /* add the dhdl's */
-    for (i=0;i<efptNR;i++)
     {
-        if (ir->fepvals->separate_dvdl[i])
+        gmx_bool bExpanded=FALSE;
+        gmx_bool bEnergy=FALSE;
+        gmx_bool bPV=FALSE;
+        int n_lambda_components=0;
+
+        /* first count the number of states */
+
+        /* add the dhdl's */
+        if (fep->dhdl_derivatives == edhdlderivativesYES)
         {
-            dhc->ndh+=1;
+            for (i=0;i<efptNR;i++)
+            {
+                if (ir->fepvals->separate_dvdl[i])
+                {
+                    dhc->ndh+=1;
+                    dhc->ndhdl+=1;
+                }
+            }
         }
-    }
+        /* add the lambdas */
+        dhc->nlambda = ir->fepvals->lambda_stop_n - ir->fepvals->lambda_start_n;
+        dhc->ndh += dhc->nlambda;
+        /* another compatibility check */
+        if (dhc->start_lambda < 0)
+        {
+            /* include one more for the specification of the state, by lambda or
+               fep_state*/
+            if (ir->expandedvals->elmcmove > elmcmoveNO) {
+                dhc->ndh +=1;
+                bExpanded=TRUE;
+            }
+            /* whether to print energies */
+            if (ir->fepvals->bPrintEnergy) {
+                dhc->ndh += 1;
+                bEnergy=TRUE;
+            }
+            if (ir->epc > epcNO) {
+                dhc->ndh += 1;  /* include pressure-volume work */
+                bPV=TRUE;
+            }
+        }
+        /* allocate them */
+        snew(dhc->dh, dhc->ndh);
+
+        /* now initialize them */
+        /* the order, for now, must match that of the dhdl.xvg file because of
+           how g_energy -odh is implemented */
+        n=0;
+        if (bExpanded)
+        {
+            dhc->dh_expanded=dhc->dh+n;
+            mde_delta_h_init(dhc->dh+n, ir->fepvals->dh_hist_size,
+                             ir->fepvals->dh_hist_spacing, ndhmax,
+                             dhbtEXPANDED, 0, 0, NULL);
+            n++;
+        }
+        if (bEnergy)
+        {
+            dhc->dh_energy=dhc->dh+n;
+            mde_delta_h_init(dhc->dh+n, ir->fepvals->dh_hist_size,
+                             ir->fepvals->dh_hist_spacing, ndhmax,
+                             dhbtEN, 0, 0, NULL);
+            n++;
+        }
+        /* add the dhdl's */
+        n_lambda_components=0;
+        if (fep->dhdl_derivatives == edhdlderivativesYES)
+        {
+            dhc->dh_dhdl = dhc->dh + n;
+            for (i=0;i<efptNR;i++)
+            {
+                if (ir->fepvals->separate_dvdl[i])
+                {
+                    /* we give it init_lambda for compatibility */
+                    mde_delta_h_init(dhc->dh+n, ir->fepvals->dh_hist_size,
+                                     ir->fepvals->dh_hist_spacing, ndhmax,
+                                     dhbtDHDL, n_lambda_components, 1,
+                                     &(fep->init_lambda));
+                    n++;
+                    n_lambda_components++;
+                }
+            }
+        }
+        else
+        {
+            for (i=0;i<efptNR;i++)
+            {
+                if (ir->fepvals->separate_dvdl[i])
+                {
+                    n_lambda_components++; /* count the components */
+                }
+            }
 
-    /* add the lambdas */
-    dhc->ndh += ir->fepvals->n_lambda;
+        }
+        /* add the lambdas */
+        dhc->dh_du = dhc->dh + n;
+        snew(lambda_vec, n_lambda_components);
+        for(i=ir->fepvals->lambda_start_n;i<ir->fepvals->lambda_stop_n;i++)
+        {
+            int k=0;
 
-    if (ir->epc > epcNO) {
-        dhc->ndh += 1;  /* include pressure-volume work */
-    }
+            for(j=0;j<efptNR;j++)
+            {
+                if (ir->fepvals->separate_dvdl[j])
+                {
+                    lambda_vec[k++] = fep->all_lambda[j][i];
+                }
+            }
 
-    snew(dhc->dh, dhc->ndh);
-    for(i=0;i<dhc->ndh;i++)
-    {
-        mde_delta_h_init(dhc->dh+i, ir->fepvals->dh_hist_size,
-                         ir->fepvals->dh_hist_spacing, ndhmax);
+            mde_delta_h_init(dhc->dh+n, ir->fepvals->dh_hist_size,
+                             ir->fepvals->dh_hist_spacing, ndhmax,
+                             dhbtDH, 0, n_lambda_components, lambda_vec);
+            n++;
+        }
+        sfree(lambda_vec);
+        if (bPV)
+        {
+            dhc->dh_pv=dhc->dh+n;
+            mde_delta_h_init(dhc->dh+n, ir->fepvals->dh_hist_size,
+                             ir->fepvals->dh_hist_spacing, ndhmax,
+                             dhbtPV, 0, 0, NULL);
+            n++;
+        }
     }
 }
 
@@ -362,16 +555,11 @@ void mde_delta_h_coll_add_dh(t_mde_delta_h_coll *dhc,
                              double fep_state,
                              double energy,
                              double pV,
-                             int bExpanded,
-                             int bPrintEnergy,
-                             int bPressure,
-                             int ndhdl,
-                             int nlambda,
                              double *dhdl,
                              double *foreign_dU,
                              double time)
 {
-    int i,n;
+    int i;
 
     if (!dhc->start_time_set)
     {
@@ -379,37 +567,31 @@ void mde_delta_h_coll_add_dh(t_mde_delta_h_coll *dhc,
         dhc->start_time=time;
     }
 
-    n = 0;
-    if (bExpanded)
+    for (i=0;i<dhc->ndhdl;i++)
     {
-        mde_delta_h_add_dh(dhc->dh+n,fep_state,time);
-        n++;
+        mde_delta_h_add_dh(dhc->dh_dhdl+i, dhdl[i], time);
     }
-    if (bPrintEnergy)
+    for (i=0;i<dhc->nlambda;i++)
     {
-        mde_delta_h_add_dh(dhc->dh+n,energy,time);
-        n++;
+        mde_delta_h_add_dh(dhc->dh_du+i, foreign_dU[i], time);
     }
-    for (i=0;i<ndhdl;i++)
+    if (dhc->dh_pv != NULL)
     {
-        mde_delta_h_add_dh(dhc->dh+n, dhdl[i], time);
-        n++;
+        mde_delta_h_add_dh(dhc->dh_pv, pV, time);
     }
-    for (i=0;i<nlambda;i++)
+    if (dhc->dh_energy != NULL)
     {
-        mde_delta_h_add_dh(dhc->dh+n, foreign_dU[i], time);
-        n++;
+        mde_delta_h_add_dh(dhc->dh_energy,energy,time);
     }
-    if (bPressure)
+    if (dhc->dh_expanded != NULL)
     {
-        mde_delta_h_add_dh(dhc->dh+n, pV, time);
-        n++;
+        mde_delta_h_add_dh(dhc->dh_expanded,fep_state,time);
     }
-}
 
-/* write the data associated with all the du blocks, but not the blocks
-   themselves. Essentially, the metadata.  Or -- is this generated every time?*/
+}
 
+/* write the metadata associated with all the du blocks, and call
+   handle_block to write out all the du blocks */
 void mde_delta_h_coll_handle_block(t_mde_delta_h_coll *dhc,
                                    t_enxframe *fr, int nblock)
 {
@@ -421,18 +603,49 @@ void mde_delta_h_coll_handle_block(t_mde_delta_h_coll *dhc,
     add_blocks_enxframe(fr, nblock);
     blk=fr->block + (nblock-1);
 
-    add_subblocks_enxblock(blk, 1);
+    /* only allocate lambda vector component blocks if they must be written out
+       for backward compatibility */
+    if (dhc->native_lambda_components!=NULL)
+    {
+        add_subblocks_enxblock(blk, 2);
+    }
+    else
+    {
+        add_subblocks_enxblock(blk, 1);
+    }
 
     dhc->subblock_d[0] = dhc->temperature; /* temperature */
     dhc->subblock_d[1] = dhc->start_time; /* time of first sample */
     dhc->subblock_d[2] = dhc->delta_time; /* time difference between samples */
-    dhc->subblock_d[3] = dhc->start_lambda; /* lambda at starttime */
+    dhc->subblock_d[3] = dhc->start_lambda; /* old-style lambda at starttime */
     dhc->subblock_d[4] = dhc->delta_lambda; /* lambda diff. between samples */
+    /* set the lambda vector components if they exist */
+    if (dhc->native_lambda_components!=NULL)
+    {
+        for(i=0;i<dhc->n_lambda_vec;i++)
+        {
+            dhc->subblock_d[5+i] = dhc->native_lambda_vec[i];
+        }
+    }
     blk->id=enxDHCOLL;
-    blk->sub[0].nr=5;
+    blk->sub[0].nr=5 + dhc->n_lambda_vec;
     blk->sub[0].type=xdr_datatype_double;
     blk->sub[0].dval=dhc->subblock_d;
 
+    if (dhc->native_lambda_components != NULL)
+    {
+        dhc->subblock_i[0] = dhc->lambda_index;
+        /* set the lambda vector component IDs if they exist */
+        dhc->subblock_i[1] = dhc->n_lambda_vec;
+        for(i=0;i<dhc->n_lambda_vec;i++)
+        {
+            dhc->subblock_i[i+2] = dhc->native_lambda_components[i];
+        }
+        blk->sub[1].nr=2 + dhc->n_lambda_vec;
+        blk->sub[1].type=xdr_datatype_int;
+        blk->sub[1].ival=dhc->subblock_i;
+    }
+
     for(i=0;i<dhc->ndh;i++)
     {
         nblock++;
index bb4ffd21ed607e4fac913ce3cd36d513a371ba97..1db14b6d8361c3305edb84f6aed5a338a113a49f 100644 (file)
 extern "C" {
 #endif
 
+
 /* The functions & data structures here describe writing
    energy differences (or their histogram )for use with g_bar */
 
 /* Data for one foreign lambda, or derivative. */
 typedef struct
 {
-    real *dh; /* the raw energy difference data -- actually, store more in here. */
+    real *dh; /* the raw energy data. */
     float *dhf; /* raw difference data -- in floats, for storage. */
     unsigned int ndh; /* number of data points */
     unsigned int ndhmax; /* the maximum number of points */
@@ -66,13 +67,21 @@ typedef struct
                               of the histogram */
     unsigned int maxbin[2]; /* highest bin number with data */
 
-    gmx_bool derivative; /* whether this delta_h contains derivatives */
-    double lambda; /* current lambda */
+    int type;       /* the block type according to dhbtDH, etc. */
+    int derivative; /* The derivative direction (as an index in the lambda
+                       vector) if this delta_h contains derivatives */
+    double *lambda; /* lambda vector (or NULL if not applicable) */
+    int nlambda;    /* length of the lambda vector */
     gmx_bool written;    /* whether this data has already been written out */
 
-    double subblock_d[4]; /* data for an mdebin subblock for I/O. */
-    gmx_large_int_t subblock_l[4]; /* data for an mdebin subblock for I/O.  */
-    int subblock_i[4]; /* data for an mdebin subblock for I/O.  */
+    gmx_large_int_t subblock_meta_l[5]; /* metadata for an mdebin subblock for
+                                           I/O: for histogram counts, etc.*/
+    double *subblock_meta_d; /* metadata subblock for I/O, used for
+                                communicating doubles (i.e. the lambda
+                                vector) */
+    int subblock_meta_i[4]; /* metadata subblock for I/O, used for
+                               communicating ints (i.e. derivative indices,
+                               etc.) */
 } t_mde_delta_h;
 
 /* the type definition is in mdebin_bar.h */
@@ -80,13 +89,39 @@ struct t_mde_delta_h_coll
 {
     t_mde_delta_h *dh; /* the delta h data */
     int ndh; /* the number of delta_h structures */
+
+    int nlambda; /* number of bar dU delta_h structures */
+    t_mde_delta_h *dh_du; /* the delta h data (pointer into dh) */
+
+    int ndhdl; /* number of bar dU delta_h structures */
+    t_mde_delta_h *dh_dhdl; /* the dhdl data (pointer into dh) */
+
+    t_mde_delta_h *dh_energy; /* energy output block (pointer into dh) */
+    t_mde_delta_h *dh_pv; /* pV output block (pointer into dh) */
+    t_mde_delta_h *dh_expanded; /* expanded ensemble output block (pointer 
+                                   into dh) */
+
     double start_time; /* start time of the current dh collection */
     double delta_time; /* time difference between samples */
     gmx_bool start_time_set; /* whether the start time has been set */
     double start_lambda; /* starting lambda for continuous motion of state*/
     double delta_lambda; /* delta lambda, for continuous motion of state */
     double temperature; /* the temperature of the samples*/
-    double subblock_d[5]; /* data for writing an mdebin subblock for I/O */
+
+    double *native_lambda_vec; /* The lambda vector describing the current
+                                  lambda state if it is set (NULL otherwise) */
+    int n_lambda_vec; /* the size of the native lambda vector */
+    int *native_lambda_components; /* the native lambda (and by extension,
+                                      foreign lambda) components in terms
+                                      of efptFEP, efptMASS, etc. */
+    int lambda_index; /* the lambda_fep_state */
+
+    double *subblock_d; /* for writing a metadata mdebin subblock for I/O */
+    int *subblock_i; /* for writing a metadata mdebin subblock for I/O */
+
+    double *lambda_vec_subblock; /* native lambda vector data subblock for
+                                    I/O */
+    int *lambda_index_subblock; /* lambda vector index data subblock for I/O */
 };
 
 
@@ -112,11 +147,6 @@ void mde_delta_h_coll_add_dh(t_mde_delta_h_coll *dhc,
                              double fep_state,
                              double energy,
                              double pV,
-                             int bExpanded,
-                             int bPrintEnergy,
-                             int bPressure,
-                             int ndhdl,
-                             int nlambda,
                              double *dhdl,
                              double *foreign_dU,
                              double time);
index 196c439947268084a5befe6d5e45dc7b99f6856f..ae828bb855d4dcac9557c32a00678cfef9c24331 100644 (file)
@@ -1448,6 +1448,11 @@ double do_lbfgs(FILE *fplog,t_commrec *cr,
 
   if (PAR(cr))
     gmx_fatal(FARGS,"Cannot do parallel L-BFGS Minimization - yet.\n");
+  
+  if (NULL != constr)
+  {
+      gmx_fatal(FARGS,"The combination of constraints and L-BFGS minimization is not implemented. Either do not use constraints, or use another minimizer (e.g. steepest descent).");
+  }
 
   n = 3*state->natoms;
   nmaxcorr = inputrec->nbfgscorr;
index 09e53c24b3425da48727e3677f425b92100f16a1..27ac6045c005580d195faf174e665b795d2abdf8 100644 (file)
@@ -199,6 +199,8 @@ static inline int calc_shmem_required(int kver)
         /* NOTE: with the default kernel on sm3.0 we need shmem only for pre-loading */
         /* i-atom x+q in shared memory */
         shmem  = NCL_PER_SUPERCL * CL_SIZE * sizeof(float4);
+        /* cj in shared memory, for both warps separately */
+        shmem += 2 * NBNXN_GPU_JGROUP_SIZE * sizeof(int);
 #ifdef IATYPE_SHMEM
         /* i-atom types in shared memory */
         shmem += NCL_PER_SUPERCL * CL_SIZE * sizeof(int);
index a323b95c3e7ffab9ebe10e3d1fbc9346b5d2958f..bea220b4c5d90a75ae170b40a6142ade326e6647 100644 (file)
@@ -68,6 +68,21 @@ extern void nbnxn_cuda_set_cacheconfig(cuda_dev_info_t *devinfo);
 extern const struct texture<float, 1, cudaReadModeElementType>& nbnxn_cuda_get_nbfp_texref();
 extern const struct texture<float, 1, cudaReadModeElementType>& nbnxn_cuda_get_coulomb_tab_texref();
 
+/* We should actually be using md_print_warn in md_logging.c,
+ * but we can't include mpi.h in CUDA code.
+ */
+static void md_print_warn(FILE *fplog, const char *buf)
+{
+    if (fplog != NULL)
+    {
+        /* We should only print to stderr on the master node,
+         * in most cases fplog is only set on the master node, so this works.
+         */
+        fprintf(stderr, "\n%s\n", buf);
+        fprintf(fplog,  "\n%s\n", buf);
+    }
+}
+
 /* Fw. decl. */
 static void nbnxn_cuda_clear_e_fshift(nbnxn_cuda_ptr_t cu_nb);
 
@@ -392,7 +407,8 @@ void nbnxn_cuda_init(FILE *fplog,
     cudaError_t stat;
     nbnxn_cuda_ptr_t  nb;
     char sbuf[STRLEN];
-    bool bStreamSync, bNoStreamSync, bTMPIAtomics, bX86;
+    bool bStreamSync, bNoStreamSync, bTMPIAtomics, bX86, bOldDriver;
+    int cuda_drv_ver;
 
     assert(gpu_info);
 
@@ -444,6 +460,13 @@ void nbnxn_cuda_init(FILE *fplog,
      * waiting to preserve performance. This requires support for atomic
      * operations and only works on x86/x86_64.
      * With polling wait event-timing also needs to be disabled.
+     *
+     * The overhead is greatly reduced in API v5.0 drivers and the improvement
+     $ is independent of runtime version. Hence, with API v5.0 drivers and later
+     * we won't switch to polling.
+     *
+     * NOTE: Unfortunately, this is known to fail when GPUs are shared by (t)MPI,
+     * ranks so we will also disable it in that case.
      */
 
     bStreamSync    = getenv("GMX_CUDA_STREAMSYNC") != NULL;
@@ -466,61 +489,55 @@ void nbnxn_cuda_init(FILE *fplog,
         gmx_fatal(FARGS, "Conflicting environment variables: both GMX_CUDA_STREAMSYNC and GMX_NO_CUDA_STREAMSYNC defined");
     }
 
+    stat = cudaDriverGetVersion(&cuda_drv_ver);
+    CU_RET_ERR(stat, "cudaDriverGetVersion failed");
+    bOldDriver = (cuda_drv_ver < 5000);
+
     if (nb->dev_info->prop.ECCEnabled == 1)
     {
         if (bStreamSync)
         {
             nb->bUseStreamSync = true;
 
-            sprintf(sbuf,
-                    "NOTE: Using a GPU with ECC enabled, but cudaStreamSynchronize-based waiting is\n"
-                    "      forced by the GMX_CUDA_STREAMSYNC env. var. Due to a CUDA bug, this \n"
-                    "      combination causes performance loss.");
-            fprintf(stderr, "\n%s\n", sbuf);
-            if (fplog)
+            /* only warn if polling should be used */
+            if (bOldDriver && !gpu_info->bDevShare)
             {
-                fprintf(fplog, "\n%s\n", sbuf);
+                md_print_warn(fplog,
+                              "NOTE: Using a GPU with ECC enabled and CUDA driver API version <5.0, but\n"
+                              "      cudaStreamSynchronize waiting is forced by the GMX_CUDA_STREAMSYNC env. var.\n");
             }
         }
         else
         {
-            /* can use polling wait only on x86/x86_64 *if* atomics are available */
-            nb->bUseStreamSync = ((bX86 && bTMPIAtomics) == false);
-
-            if (!bX86)
+            /* Can/should turn of cudaStreamSynchronize wait only if
+             *   - we're on x86/x86_64
+             *   - atomics are available
+             *   - GPUs are not being shared
+             *   - and driver is old. */
+            nb->bUseStreamSync =
+                (bX86 && bTMPIAtomics && !gpu_info->bDevShare && bOldDriver) ?
+                true : false;
+
+            if (nb->bUseStreamSync)
             {
-                sprintf(sbuf,
-                        "Using a GPU with ECC on; the standard cudaStreamSynchronize waiting, due to a\n"
-                        "      CUDA bug, causes performance loss when used in combination with ECC.\n"
-                        "      However, the polling waiting workaround can not be used as it is only\n"
-                        "      supported on x86/x86_64, but not on the current architecture.");
-                gmx_warning("%s\n", sbuf);
-                if (fplog)
-                {
-                    fprintf(fplog, "\n%s\n", sbuf);
-                }
-
+                md_print_warn(fplog,
+                              "NOTE: Using a GPU with ECC enabled and CUDA driver API version <5.0, known to\n"
+                              "      cause performance loss. Switching to the alternative polling GPU waiting.\n"
+                              "      If you encounter issues, switch back to standard GPU waiting by setting\n"
+                              "      the GMX_CUDA_STREAMSYNC environment variable.\n");
             }
-            else if (bTMPIAtomics)
-            {
-                if (fplog)
-                {
-                    fprintf(fplog,
-                            "NOTE: Using a GPU with ECC enabled; will use polling waiting.\n");
-                }
-            }
-            else
+            else if (bOldDriver)
             {
+                /* Tell the user that the ECC+old driver combination can be bad */
                 sprintf(sbuf,
-                        "Using a GPU with ECC on; the standard cudaStreamSynchronize waiting, due to a\n"
-                        "      CUDA bug, causes performance loss when used in combination with ECC.\n"
-                        "      However, the polling waiting workaround can not be used as atomic\n"
-                        "      operations are not supported by the current CPU+compiler combination.");
-                gmx_warning("%s\n", sbuf);
-                if (fplog)
-                {
-                    fprintf(fplog, "\n%s\n", sbuf);
-                }
+                        "NOTE: Using a GPU with ECC enabled and CUDA driver API version <5.0. A bug in this\n"
+                        "      driver can cause performance loss.\n"
+                        "      However, the polling waiting workaround can not be used because\n%s\n"
+                        "      Consider updating the driver or turning ECC off.",
+                        (!bX86 || !bTMPIAtomics) ?
+                           "         atomic operations are not supported by the platform/CPU+compiler." :
+                           "         GPU(s) are being oversubscribed.");
+                md_print_warn(fplog, sbuf);
             }
         }
     }
@@ -530,14 +547,8 @@ void nbnxn_cuda_init(FILE *fplog,
         {
             nb->bUseStreamSync = false;
 
-            sprintf(sbuf,
-                    "NOTE: Using a GPU with no/disabled ECC, but cudaStreamSynchronize-based waiting\n"
-                    "      is turned off and polling turned on by the GMX_NO_CUDA_STREAMSYNC env. var.");
-            fprintf(stderr, "\n%s\n", sbuf);
-            if (fplog)
-            {
-                fprintf(fplog, "\n%s\n", sbuf);
-            }
+            md_print_warn(fplog,
+                          "NOTE: Polling wait for GPU synchronization requested by GMX_NO_CUDA_STREAMSYNC\n");
         }
         else
         {
index 22c6bb931801c58072e04aafe569ac8c8bb14b26..c7ab7cc6c62fc2db701e8b7df5d451ca8f9278fa 100644 (file)
@@ -139,9 +139,11 @@ __global__ void NB_KERNEL_FUNC_NAME(k_nbnxn)
 
     /* shmem buffer for i x+q pre-loading */
     extern __shared__  float4 xqib[];
+    /* shmem buffer for cj, for both warps separately */
+    int *cjs     = (int *)(xqib + NCL_PER_SUPERCL * CL_SIZE);
 #ifdef IATYPE_SHMEM
     /* shmem buffer for i atom-type pre-loading */
-    int *atib = (int *)(xqib + NCL_PER_SUPERCL * CL_SIZE);
+    int *atib = (int *)(cjs + 2 * NBNXN_GPU_JGROUP_SIZE);
 #endif
 
 #ifndef REDUCE_SHUFFLE
@@ -149,7 +151,7 @@ __global__ void NB_KERNEL_FUNC_NAME(k_nbnxn)
 #ifdef IATYPE_SHMEM
     float *f_buf = (float *)(atib + NCL_PER_SUPERCL * CL_SIZE);
 #else
-    float *f_buf = (float *)(xqib + NCL_PER_SUPERCL * CL_SIZE);
+    float *f_buf = (float *)(cjs + 2 * NBNXN_GPU_JGROUP_SIZE);
 #endif
 #endif
 
@@ -219,6 +221,12 @@ __global__ void NB_KERNEL_FUNC_NAME(k_nbnxn)
         if (imask)
 #endif
         {
+            /* Pre-load cj into shared memory on both warps separately */
+            if ((tidxj == 0 || tidxj == 4) && tidxi < NBNXN_GPU_JGROUP_SIZE)
+            {
+                cjs[tidxi + tidxj * NBNXN_GPU_JGROUP_SIZE / 4] = pl_cj4[j4].cj[tidxi];
+            }
+
             /* Unrolling this loop
                - with pruning leads to register spilling;
                - on Kepler is much slower;
@@ -233,7 +241,7 @@ __global__ void NB_KERNEL_FUNC_NAME(k_nbnxn)
                 {
                     mask_ji = (1U << (jm * NCL_PER_SUPERCL));
 
-                    cj      = pl_cj4[j4].cj[jm];
+                    cj      = cjs[jm + (tidxj & 4) * NBNXN_GPU_JGROUP_SIZE / 4];
                     aj      = cj * CL_SIZE + tidxj;
 
                     /* load j atom data */
index 5b16fc06a7326e90b870e86a9aee0ee89260229b..d0f32ee8e1b8e3ce4c8bdfcc74c72912315474fe 100644 (file)
@@ -4800,6 +4800,7 @@ void nbnxn_make_pairlist(const nbnxn_search_t nbs,
                          t_nrnb *nrnb)
 {
     nbnxn_grid_t *gridi,*gridj;
+    gmx_bool bGPUCPU;
     int nzi,zi,zj0,zj1,zj;
     int nsubpair_max;
     int th;
@@ -4809,6 +4810,9 @@ void nbnxn_make_pairlist(const nbnxn_search_t nbs,
     gmx_bool CombineNBLists;
     int np_tot,np_noq,np_hlj,nap;
 
+    /* Check if we are running hybrid GPU + CPU nbnxn mode */
+    bGPUCPU = (!nbs->grid[0].bSimple && nbl_list->bSimple);
+
     nnbl            = nbl_list->nnbl;
     nbl             = nbl_list->nbl;
     CombineNBLists  = nbl_list->bCombined;
@@ -4819,7 +4823,8 @@ void nbnxn_make_pairlist(const nbnxn_search_t nbs,
     }
 
     nbat->bUseBufferFlags = (nbat->nout > 1);
-    if (nbat->bUseBufferFlags && LOCAL_I(iloc))
+    /* We should re-init the flags before making the first list */
+    if (nbat->bUseBufferFlags && (LOCAL_I(iloc) || bGPUCPU))
     {
         init_buffer_flags(&nbat->buffer_flags,nbat->natoms);
     }
@@ -4916,7 +4921,11 @@ void nbnxn_make_pairlist(const nbnxn_search_t nbs,
 #pragma omp parallel for num_threads(nnbl) schedule(static)
             for(th=0; th<nnbl; th++)
             {
-                if (nbat->bUseBufferFlags && zi == 0 && zj == 0)
+                /* Re-init the thread-local work flag data before making
+                 * the first list (not an elegant conditional).
+                 */
+                if (nbat->bUseBufferFlags && ((zi == 0 && zj == 0) ||
+                                              (bGPUCPU && zi == 0 && zj == 1)))
                 {
                     init_buffer_flags(&nbs->work[th].buffer_flags,nbat->natoms);
                 }
index 5ef37b5f5cdfa51e548b46831203edddb9e4ffd3..52b376493e0ff35d8cd5e531d8637a2bef3ed913 100644 (file)
 /* mopac interface routines */
 
 
-#ifndef F77_FUNC
-#define F77_FUNC(name,NAME) name ## _
-#endif
-
-
 void 
 F77_FUNC(inigms,IMIGMS)(void);
 
index d11e9a25f37aae40942e2753842287f1292142df..546f94bb14a12aa3c924eed30db5c58a4d07e7d7 100644 (file)
 
 
 /* mopac interface routines */
-
-#ifndef F77_FUNC
-#define F77_FUNC(name,NAME) name ## _
-#endif
-
-
 void 
 F77_FUNC(domldt,DOMLDT)(int *nrqmat, int labels[], char keywords[]);
 
index 932fc34f225b47acba1c4b643a6cbb580bda7676..87cf5630e1618bcb78e068bbd09383597a10e290 100644 (file)
@@ -68,6 +68,7 @@
 #include "orires.h"
 #include "gmx_wallcycle.h"
 #include "gmx_omp_nthreads.h"
+#include "gmx_omp.h"
 
 /*For debugging, start at v(-dt/2) for velolcity verlet -- uncomment next line */
 /*#define STARTFROMDT2*/
@@ -90,8 +91,12 @@ typedef struct {
 } gmx_sd_sigma_t;
 
 typedef struct {
-  /* The random state */
-  gmx_rng_t gaussrand;
+  /* The random state for ngaussrand threads.
+   * Normal thermostats need just 1 random number generator,
+   * but SD and BD with OpenMP parallelization need 1 for each thread.
+   */
+  int ngaussrand;
+  gmx_rng_t *gaussrand;
   /* BD stuff */
   real *bd_rf;
   /* SD stuff */
@@ -467,11 +472,42 @@ static void do_update_visc(int start,int nrend,double dt,
     }
 }
 
-static gmx_stochd_t *init_stochd(FILE *fplog,t_inputrec *ir)
+/* Allocates and initializes sd->gaussrand[i] for i=1, i<sd->ngaussrand,
+ * Using seeds generated from sd->gaussrand[0].
+ */
+static void init_multiple_gaussrand(gmx_stochd_t *sd)
+{
+    int          ngr,i;
+    unsigned int *seed;
+
+    ngr = sd->ngaussrand;
+    snew(seed,ngr);
+
+    for(i=1; i<ngr; i++)
+    {
+        seed[i] = gmx_rng_uniform_uint32(sd->gaussrand[0]);
+    }
+
+#pragma omp parallel num_threads(ngr)
+    {
+        int th;
+
+        th = gmx_omp_get_thread_num();
+        if (th > 0)
+        {
+            /* Initialize on each thread to have thread-local memory alloced */
+            sd->gaussrand[th] = gmx_rng_init(seed[th]);
+        }
+    }
+
+    sfree(seed);
+}
+
+static gmx_stochd_t *init_stochd(FILE *fplog,t_inputrec *ir,int nthreads)
 {
     gmx_stochd_t *sd;
     gmx_sd_const_t *sdc;
-    int  ngtc,n;
+    int  ngtc,n,th;
     real y;
 
     snew(sd,1);
@@ -479,7 +515,26 @@ static gmx_stochd_t *init_stochd(FILE *fplog,t_inputrec *ir)
     /* Initiate random number generator for langevin type dynamics,
      * for BD, SD or velocity rescaling temperature coupling.
      */
-    sd->gaussrand = gmx_rng_init(ir->ld_seed);
+    if (ir->eI == eiBD || EI_SD(ir->eI))
+    {
+        sd->ngaussrand = nthreads;
+    }
+    else
+    {
+        sd->ngaussrand = 1;
+    }
+    snew(sd->gaussrand,sd->ngaussrand);
+
+    /* Initialize the first random generator */
+    sd->gaussrand[0] = gmx_rng_init(ir->ld_seed);
+
+    if (sd->ngaussrand > 1)
+    {
+        /* Initialize the rest of the random number generators,
+         * using the first one to generate seeds.
+         */
+        init_multiple_gaussrand(sd);
+    }
 
     ngtc = ir->opts.ngtc;
 
@@ -561,12 +616,38 @@ static gmx_stochd_t *init_stochd(FILE *fplog,t_inputrec *ir)
 
 void get_stochd_state(gmx_update_t upd,t_state *state)
 {
-    gmx_rng_get_state(upd->sd->gaussrand,state->ld_rng,state->ld_rngi);
+    /* Note that we only get the state of the first random generator,
+     * even if there are multiple. This avoids repetition.
+     */
+    gmx_rng_get_state(upd->sd->gaussrand[0],state->ld_rng,state->ld_rngi);
 }
 
 void set_stochd_state(gmx_update_t upd,t_state *state)
 {
-    gmx_rng_set_state(upd->sd->gaussrand,state->ld_rng,state->ld_rngi[0]);
+    gmx_stochd_t *sd;
+    int i;
+
+    sd = upd->sd;
+
+    gmx_rng_set_state(sd->gaussrand[0],state->ld_rng,state->ld_rngi[0]);
+
+    if (sd->ngaussrand > 1)
+    {
+        /* We only end up here with SD or BD with OpenMP.
+         * Destroy and reinitialize the rest of the random number generators,
+         * using seeds generated from the first one.
+         * Although this doesn't recover the previous state,
+         * it at least avoids repetition, which is most important.
+         * Exaclty restoring states with all MPI+OpenMP setups is difficult
+         * and as the integrator is random to start with, doesn't gain us much.
+         */
+        for(i=1; i<sd->ngaussrand; i++)
+        {
+            gmx_rng_destroy(sd->gaussrand[i]);
+        }
+
+        init_multiple_gaussrand(sd);
+    }
 }
 
 gmx_update_t init_update(FILE *fplog,t_inputrec *ir)
@@ -577,7 +658,7 @@ gmx_update_t init_update(FILE *fplog,t_inputrec *ir)
 
     if (ir->eI == eiBD || EI_SD(ir->eI) || ir->etc == etcVRESCALE || ETC_ANDERSEN(ir->etc))
     {
-        upd->sd = init_stochd(fplog,ir);
+        upd->sd = init_stochd(fplog,ir,gmx_omp_nthreads_get(emntUpdate));
     }
 
     upd->xp = NULL;
@@ -590,7 +671,8 @@ gmx_update_t init_update(FILE *fplog,t_inputrec *ir)
 }
 
 static void do_update_sd1(gmx_stochd_t *sd,
-                          int start,int homenr,double dt,
+                          gmx_rng_t gaussrand,
+                          int start,int nrend,double dt,
                           rvec accel[],ivec nFreeze[],
                           real invmass[],unsigned short ptype[],
                           unsigned short cFREEZE[],unsigned short cACC[],
@@ -601,7 +683,6 @@ static void do_update_sd1(gmx_stochd_t *sd,
 {
   gmx_sd_const_t *sdc;
   gmx_sd_sigma_t *sig;
-  gmx_rng_t gaussrand;
   real   kT;
   int    gf=0,ga=0,gt=0;
   real   ism,sd_V;
@@ -609,12 +690,11 @@ static void do_update_sd1(gmx_stochd_t *sd,
 
   sdc = sd->sdc;
   sig = sd->sdsig;
-  if (homenr > sd->sd_V_nalloc)
+  if (nrend-start > sd->sd_V_nalloc)
   {
-      sd->sd_V_nalloc = over_alloc_dd(homenr);
+      sd->sd_V_nalloc = over_alloc_dd(nrend-start);
       srenew(sd->sd_V,sd->sd_V_nalloc);
   }
-  gaussrand = sd->gaussrand;
 
   for(n=0; n<ngtc; n++)
   {
@@ -623,7 +703,7 @@ static void do_update_sd1(gmx_stochd_t *sd,
       sig[n].V  = sqrt(kT*(1 - sdc[n].em*sdc[n].em));
   }
 
-  for(n=start; n<start+homenr; n++)
+  for(n=start; n<nrend; n++)
   {
       ism = sqrt(invmass[n]);
       if (cFREEZE)
@@ -660,8 +740,10 @@ static void do_update_sd1(gmx_stochd_t *sd,
   }
 }
 
-static void do_update_sd2(gmx_stochd_t *sd,gmx_bool bInitStep,
-                          int start,int homenr,
+static void do_update_sd2(gmx_stochd_t *sd,
+                          gmx_rng_t gaussrand,
+                          gmx_bool bInitStep,
+                          int start,int nrend,
                           rvec accel[],ivec nFreeze[],
                           real invmass[],unsigned short ptype[],
                           unsigned short cFREEZE[],unsigned short cACC[],
@@ -677,7 +759,6 @@ static void do_update_sd2(gmx_stochd_t *sd,gmx_bool bInitStep,
    * half of the update, needs to be remembered for the second half.
    */
   rvec *sd_V;
-  gmx_rng_t gaussrand;
   real   kT;
   int    gf=0,ga=0,gt=0;
   real   vn=0,Vmh,Xmh;
@@ -686,13 +767,12 @@ static void do_update_sd2(gmx_stochd_t *sd,gmx_bool bInitStep,
 
   sdc = sd->sdc;
   sig = sd->sdsig;
-  if (homenr > sd->sd_V_nalloc)
+  if (nrend-start > sd->sd_V_nalloc)
   {
-      sd->sd_V_nalloc = over_alloc_dd(homenr);
+      sd->sd_V_nalloc = over_alloc_dd(nrend-start);
       srenew(sd->sd_V,sd->sd_V_nalloc);
   }
   sd_V = sd->sd_V;
-  gaussrand = sd->gaussrand;
 
   if (bFirstHalf)
   {
@@ -707,7 +787,7 @@ static void do_update_sd2(gmx_stochd_t *sd,gmx_bool bInitStep,
       }
   }
 
-  for (n=start; n<start+homenr; n++)
+  for (n=start; n<nrend; n++)
   {
       ism = sqrt(invmass[n]);
       if (cFREEZE)
@@ -1297,7 +1377,7 @@ void update_tcouple(FILE         *fplog,
             break;
         case etcVRESCALE:
             vrescale_tcoupl(inputrec,ekind,dttc,
-                            state->therm_integral,upd->sd->gaussrand);
+                            state->therm_integral,upd->sd->gaussrand[0]);
             break;
         }
         /* rescale in place here */
@@ -1417,6 +1497,7 @@ void update_constraints(FILE         *fplog,
     int              start,homenr,nrend,i,n,m,g,d;
     tensor           vir_con;
     rvec             *vbuf,*xprime=NULL;
+    int              nth,th;
 
     if (constr) {bDoConstr=TRUE;}
     if (bFirstHalf && !EI_VV(inputrec->eI)) {bDoConstr=FALSE;}
@@ -1513,14 +1594,26 @@ void update_constraints(FILE         *fplog,
     {
         xprime = get_xprime(state,upd);
 
-        /* The second part of the SD integration */
-        do_update_sd2(upd->sd,FALSE,start,homenr,
-                      inputrec->opts.acc,inputrec->opts.nFreeze,
-                      md->invmass,md->ptype,
-                      md->cFREEZE,md->cACC,md->cTC,
-                      state->x,xprime,state->v,force,state->sd_X,
-                      inputrec->opts.ngtc,inputrec->opts.tau_t,
-                      inputrec->opts.ref_t,FALSE);
+        nth = gmx_omp_nthreads_get(emntUpdate);
+
+#pragma omp parallel for num_threads(nth) schedule(static)
+        for(th=0; th<nth; th++)
+        {
+            int start_th,end_th;
+
+            start_th = start + ((nrend-start)* th   )/nth;
+            end_th   = start + ((nrend-start)*(th+1))/nth;
+
+            /* The second part of the SD integration */
+            do_update_sd2(upd->sd,upd->sd->gaussrand[th],
+                          FALSE,start_th,end_th,
+                          inputrec->opts.acc,inputrec->opts.nFreeze,
+                          md->invmass,md->ptype,
+                          md->cFREEZE,md->cACC,md->cTC,
+                          state->x,xprime,state->v,force,state->sd_X,
+                          inputrec->opts.ngtc,inputrec->opts.tau_t,
+                          inputrec->opts.ref_t,FALSE);
+        }
         inc_nrnb(nrnb, eNR_UPDATE, homenr);
 
         if (bDoConstr)
@@ -1774,7 +1867,7 @@ void update_coords(FILE         *fplog,
         nth = gmx_omp_nthreads_get(emntUpdate);
     }
 
-# pragma omp parallel for num_threads(nth) schedule(static) private(alpha)
+#pragma omp parallel for num_threads(nth) schedule(static) private(alpha)
     for(th=0; th<nth; th++)
     {
         int start_th,end_th;
@@ -1808,7 +1901,8 @@ void update_coords(FILE         *fplog,
             }
             break;
         case (eiSD1):
-            do_update_sd1(upd->sd,start,homenr,dt,
+            do_update_sd1(upd->sd,upd->sd->gaussrand[th],
+                          start_th,end_th,dt,
                           inputrec->opts.acc,inputrec->opts.nFreeze,
                           md->invmass,md->ptype,
                           md->cFREEZE,md->cACC,md->cTC,
@@ -1819,7 +1913,8 @@ void update_coords(FILE         *fplog,
             /* The SD update is done in 2 parts, because an extra constraint step
              * is needed 
              */
-            do_update_sd2(upd->sd,bInitStep,start,homenr,
+            do_update_sd2(upd->sd,upd->sd->gaussrand[th],
+                          bInitStep,start_th,end_th,
                           inputrec->opts.acc,inputrec->opts.nFreeze,
                           md->invmass,md->ptype,
                           md->cFREEZE,md->cACC,md->cTC,
@@ -1828,13 +1923,13 @@ void update_coords(FILE         *fplog,
                           TRUE);
         break;
         case (eiBD):
-            do_update_bd(start,nrend,dt,
+            do_update_bd(start_th,end_th,dt,
                          inputrec->opts.nFreeze,md->invmass,md->ptype,
                          md->cFREEZE,md->cTC,
                          state->x,xprime,state->v,force,
                          inputrec->bd_fric,
                          inputrec->opts.ngtc,inputrec->opts.tau_t,inputrec->opts.ref_t,
-                         upd->sd->bd_rf,upd->sd->gaussrand);
+                         upd->sd->bd_rf,upd->sd->gaussrand[th]);
             break;
         case (eiVV):
         case (eiVVAK):
@@ -1940,7 +2035,7 @@ extern gmx_bool update_randomize_velocities(t_inputrec *ir, gmx_large_int_t step
             }
             upd->randatom_list_init = TRUE;
         }
-        andersen_tcoupl(ir,md,state,upd->sd->gaussrand,rate,
+        andersen_tcoupl(ir,md,state,upd->sd->gaussrand[0],rate,
                         (ir->etc==etcANDERSEN)?idef:NULL,
                         constr?get_nblocks(constr):0,
                         constr?get_sblock(constr):NULL,
index 3bcf86ad403184094d5701d153151ae37e4bfffc..4e90cf14b17d8bf354c57a38dcd831e2edbe9dca 100644 (file)
@@ -602,6 +602,8 @@ static void cmp_fepvals(FILE *fp,t_lambda *fep1,t_lambda *fep2,real ftol, real a
           cmp_double(fp,"inputrec->fepvals->all_lambda",-1,fep1->all_lambda[i][j],fep2->all_lambda[i][j],ftol,abstol);
       }
   }
+  cmp_int(fp,"inputrec->fepvals->lambda_neighbors",1,fep1->lambda_neighbors,
+          fep2->lambda_neighbors);
   cmp_real(fp,"inputrec->fepvals->sc_alpha",-1,fep1->sc_alpha,fep2->sc_alpha,ftol,abstol);
   cmp_int(fp,"inputrec->fepvals->sc_power",-1,fep1->sc_power,fep2->sc_power);
   cmp_real(fp,"inputrec->fepvals->sc_r_power",-1,fep1->sc_r_power,fep2->sc_r_power,ftol,abstol);
index f580688ed8105d0e0a0af163b7ea02e9e98ca3fa..4b42be324e290a1b72859e64132af73b8ee063fb 100644 (file)
@@ -442,6 +442,9 @@ int cmain(int argc,char *argv[])
     "Note that currently setting [TT]GMXLIB[tt] is the only way to customize",
     "directories used for searching include files.",
   };
+  const char *bugs[] = {
+    "Position restraint output from -sys -s is broken"
+  };
   t_filenm fnm[] = {
     { efTPX, "-s", NULL, ffOPTRD },
     { efTRX, "-f", NULL, ffOPTRD },
@@ -466,7 +469,7 @@ int cmain(int argc,char *argv[])
   
   CopyRight(stderr,argv[0]);
   parse_common_args(&argc,argv,0,NFILE,fnm,asize(pa),pa,
-                   asize(desc),desc,0,NULL,&oenv);
+                    asize(desc),desc,asize(bugs),bugs,&oenv);
 
 
   if (ftp2bSet(efTPX,NFILE,fnm))
index d7d0eec6e1c4bd2d06ee91f79d6e67dc22165541..93d385cf715e346a64ddd7f4b147a10b3c556a7b 100644 (file)
@@ -2,20 +2,15 @@ include_directories(${CMAKE_SOURCE_DIR}/src/gromacs/gmxpreprocess)
 
 set(MDRUN_SOURCES
     do_gct.c      gctio.c       genalg.c    ionize.c
-    md.c          md_openmm.c   mdrun.c     membed.c
+    md.c          mdrun.c     membed.c
     pme_loadbal.c repl_ex.c     runner.c    xutils.c
     ../main.cpp)
 
-if(GMX_OPENMM) 
-    include_directories(./gmx_gpu_utils ${OpenMM_INCLUDE_DIR})
-    link_directories(${OpenMM_LIBRARY_DIR}) 
-    # with this define no evn.var. is needed with OPENMM_PLUGIN_DIR
-    # if the same OpenMM installation is used for running and building 
-    add_definitions( -DOPENMM_PLUGIN_DIR="${OpenMM_PLUGIN_DIR}" ) 
-    file(TO_CMAKE_PATH ${OpenMM_PLUGIN_DIR} _path)
-    add_library(openmm_api_wrapper STATIC openmm_wrapper.cpp)
-    target_link_libraries(openmm_api_wrapper gmx_gpu_utils ${OpenMM_LIBRARIES})
-    set(GMX_OPENMM_LIBRARIES openmm_api_wrapper gmx_gpu_utils ${OpenMM_LIBRARIES})   
+if(GMX_OPENMM)
+    # Even though the OpenMM build has "moved to contrib", many things
+    # have be be done from within the scope of the CMakeLists.txt that
+    # builds its mdrun, and that is here
+    include(../contrib/BuildMdrunOpenMM)
 endif(GMX_OPENMM)
 
 if(GMX_FAHCORE)
@@ -23,16 +18,12 @@ if(GMX_FAHCORE)
 else(GMX_FAHCORE)
     add_executable(mdrun ${MDRUN_SOURCES})
     gmx_add_man_page(mdrun)
-    target_link_libraries(mdrun ${GMX_EXTRA_LIBRARIES} libgromacs ${GMX_OPENMM_LIBRARIES}
+    target_link_libraries(mdrun ${GMX_EXTRA_LIBRARIES} libgromacs
         ${GMX_EXE_LINKER_FLAGS})
     set_target_properties(mdrun PROPERTIES OUTPUT_NAME "mdrun${GMX_BINARY_SUFFIX}"
         COMPILE_FLAGS "${OpenMP_C_FLAGS}")
     install(TARGETS mdrun DESTINATION ${BIN_INSTALL_DIR} COMPONENT mdrun)
 
-    if(GMX_OPENMM AND MSVC)
-        set_target_properties(mdrun PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMT")
-    endif()
-
     # Create the custom install-mdrun target
     if (BUILD_SHARED_LIBS)
         # If shared libraries are used, we need to install the libraries in
index da949ade755c10c105406c0d5d0a9a81a2fb5a99..cf1dd35ec32dd75e33cda2ab0cc0aa50664929af 100644 (file)
@@ -201,7 +201,7 @@ double do_md(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
     gmx_bool        bTCR=FALSE,bConverged=TRUE,bOK,bSumEkinhOld,bExchanged;
     gmx_bool        bAppend;
     gmx_bool        bResetCountersHalfMaxH=FALSE;
-    gmx_bool        bVV,bIterations,bFirstIterate,bTemp,bPres,bTrotter;
+    gmx_bool        bVV,bIterativeCase,bFirstIterate,bTemp,bPres,bTrotter;
     gmx_bool        bUpdateDoLR;
     real        mu_aver=0,dvdl;
     int         a0,a1,gnx=0,ii;
@@ -215,7 +215,6 @@ double do_md(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
        real        vetanew = 0;
     int         lamnew=0;
     /* for FEP */
-    int         fep_state=0;
     int         nstfep;
     real        rate;
     double      cycles;
@@ -265,7 +264,11 @@ double do_md(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
         snew(cbuf,top_global->natoms);
     }
     /* all the iteratative cases - only if there are constraints */ 
-    bIterations = ((IR_NPH_TROTTER(ir) || IR_NPT_TROTTER(ir)) && (constr) && (!bRerunMD));
+    bIterativeCase = ((IR_NPH_TROTTER(ir) || IR_NPT_TROTTER(ir)) && (constr) && (!bRerunMD));
+    gmx_iterate_init(&iterate,FALSE); /* The default value of iterate->bIterationActive is set to
+                                         false in this step.  The correct value, true or false,
+                                         is set at each step, as it depends on the frequency of temperature
+                                         and pressure control.*/
     bTrotter = (bVV && (IR_NPT_TROTTER(ir) || IR_NPH_TROTTER(ir) || IR_NVT_TROTTER(ir)));
     
     if (bRerunMD)
@@ -617,7 +620,7 @@ double do_md(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
     }
     
     /* if using an iterative algorithm, we need to create a working directory for the state. */
-    if (bIterations) 
+    if (bIterativeCase)
     {
             bufstate = init_bufstate(state);
     }
@@ -1060,15 +1063,21 @@ double do_md(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
          */
         if (EI_VV(ir->eI) && (!bInitStep))
         {
-            /* for vv, the first half actually corresponds to the last step */
+            /* for vv, the first half of the integration actually corresponds
+               to the previous step.  bCalcEner is only required to be evaluated on the 'next' step,
+               but the virial needs to be calculated on both the current step and the 'next' step. Future
+               reorganization may be able to get rid of one of the bCalcVir=TRUE steps. */
+
             bCalcEner = do_per_step(step-1,ir->nstcalcenergy);
+            bCalcVir = bCalcEner ||
+                (ir->epc != epcNO && (do_per_step(step,ir->nstpcouple) || do_per_step(step-1,ir->nstpcouple)));
         }
         else
         {
             bCalcEner = do_per_step(step,ir->nstcalcenergy);
+            bCalcVir = bCalcEner ||
+                (ir->epc != epcNO && do_per_step(step,ir->nstpcouple));
         }
-        bCalcVir = bCalcEner ||
-            (ir->epc != epcNO && do_per_step(step,ir->nstpcouple));
 
         /* Do we need global communication ? */
         bGStat = (bCalcVir || bCalcEner || bStopCM ||
@@ -1183,9 +1192,9 @@ double do_md(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
                           ekind,M,wcycle,upd,bInitStep,etrtVELOCITY1,
                           cr,nrnb,constr,&top->idef);
             
-            if (bIterations)
+            if (bIterativeCase && do_per_step(step-1,ir->nstpcouple) && !bInitStep)
             {
-                gmx_iterate_init(&iterate,bIterations && !bInitStep);
+                gmx_iterate_init(&iterate,TRUE);
             }
             /* for iterations, we save these vectors, as we will be self-consistently iterating
                the calculations */
@@ -1193,14 +1202,14 @@ double do_md(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
             /*#### UPDATE EXTENDED VARIABLES IN TROTTER FORMULATION */
             
             /* save the state */
-            if (bIterations && iterate.bIterate) { 
+            if (iterate.bIterationActive) {
                 copy_coupling_state(state,bufstate,ekind,ekind_save,&(ir->opts));
             }
             
             bFirstIterate = TRUE;
-            while (bFirstIterate || (bIterations && iterate.bIterate))
+            while (bFirstIterate || iterate.bIterationActive)
             {
-                if (bIterations && iterate.bIterate) 
+                if (iterate.bIterationActive)
                 {
                     copy_coupling_state(bufstate,state,ekind_save,ekind,&(ir->opts));
                     if (bFirstIterate && bTrotter) 
@@ -1242,7 +1251,6 @@ double do_md(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
                     unshift_self(graph,state->box,state->x);
                 }
                 
-                
                 /* if VV, compute the pressure and constraints */
                 /* For VV2, we strictly only need this if using pressure
                  * control, but we really would like to have accurate pressures
@@ -1251,34 +1259,37 @@ double do_md(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
                  * For now, keep this choice in comments.
                  */
                 /*bPres = (ir->eI==eiVV || IR_NPT_TROTTER(ir)); */
-                    /*bTemp = ((ir->eI==eiVV &&(!bInitStep)) || (ir->eI==eiVVAK && IR_NPT_TROTTER(ir)));*/
+                /*bTemp = ((ir->eI==eiVV &&(!bInitStep)) || (ir->eI==eiVVAK && IR_NPT_TROTTER(ir)));*/
                 bPres = TRUE;
                 bTemp = ((ir->eI==eiVV &&(!bInitStep)) || (ir->eI==eiVVAK));
                 if (bCalcEner && ir->eI==eiVVAK)  /*MRS:  7/9/2010 -- this still doesn't fix it?*/
                 {
                     bSumEkinhOld = TRUE;
                 }
-                compute_globals(fplog,gstat,cr,ir,fr,ekind,state,state_global,mdatoms,nrnb,vcm,
-                                wcycle,enerd,force_vir,shake_vir,total_vir,pres,mu_tot,
-                                constr,NULL,FALSE,state->box,
-                                top_global,&pcurr,top_global->natoms,&bSumEkinhOld,
-                                cglo_flags 
-                                | CGLO_ENERGY 
-                                | (bTemp ? CGLO_TEMPERATURE:0) 
-                                | (bPres ? CGLO_PRESSURE : 0) 
-                                | (bPres ? CGLO_CONSTRAINT : 0)
-                                | ((bIterations && iterate.bIterate) ? CGLO_ITERATE : 0)  
-                                | (bFirstIterate ? CGLO_FIRSTITERATE : 0)
-                                | CGLO_SCALEEKIN 
-                    );
-                /* explanation of above: 
-                   a) We compute Ekin at the full time step
-                   if 1) we are using the AveVel Ekin, and it's not the
-                   initial step, or 2) if we are using AveEkin, but need the full
-                   time step kinetic energy for the pressure (always true now, since we want accurate statistics).
-                   b) If we are using EkinAveEkin for the kinetic energy for the temperture control, we still feed in 
-                   EkinAveVel because it's needed for the pressure */
-                
+                /* for vv, the first half of the integration actually corresponds to the previous step.
+                   So we need information from the last step in the first half of the integration */
+                if (bGStat || do_per_step(step-1,nstglobalcomm)) {
+                    compute_globals(fplog,gstat,cr,ir,fr,ekind,state,state_global,mdatoms,nrnb,vcm,
+                                    wcycle,enerd,force_vir,shake_vir,total_vir,pres,mu_tot,
+                                    constr,NULL,FALSE,state->box,
+                                    top_global,&pcurr,top_global->natoms,&bSumEkinhOld,
+                                    cglo_flags
+                                    | CGLO_ENERGY
+                                    | (bTemp ? CGLO_TEMPERATURE:0)
+                                    | (bPres ? CGLO_PRESSURE : 0)
+                                    | (bPres ? CGLO_CONSTRAINT : 0)
+                                    | ((iterate.bIterationActive) ? CGLO_ITERATE : 0)
+                                    | (bFirstIterate ? CGLO_FIRSTITERATE : 0)
+                                    | CGLO_SCALEEKIN
+                        );
+                    /* explanation of above:
+                       a) We compute Ekin at the full time step
+                       if 1) we are using the AveVel Ekin, and it's not the
+                       initial step, or 2) if we are using AveEkin, but need the full
+                       time step kinetic energy for the pressure (always true now, since we want accurate statistics).
+                       b) If we are using EkinAveEkin for the kinetic energy for the temperature control, we still feed in
+                       EkinAveVel because it's needed for the pressure */
+                }
                 /* temperature scaling and pressure scaling to produce the extended variables at t+dt */
                 if (!bInitStep) 
                 {
@@ -1304,7 +1315,7 @@ double do_md(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
                     }
                 }
                 
-                if (bIterations &&
+                if (iterate.bIterationActive &&
                     done_iterating(cr,fplog,step,&iterate,bFirstIterate,
                                    state->veta,&vetanew)) 
                 {
@@ -1580,21 +1591,18 @@ double do_md(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
             }
         }
 
-        if (bIterations)
-        {
-            gmx_iterate_init(&iterate,bIterations);
-        }
-    
-        /* for iterations, we save these vectors, as we will be redoing the calculations */
-        if (bIterations && iterate.bIterate) 
+        if (bIterativeCase && do_per_step(step,ir->nstpcouple))
         {
+            gmx_iterate_init(&iterate,TRUE);
+            /* for iterations, we save these vectors, as we will be redoing the calculations */
             copy_coupling_state(state,bufstate,ekind,ekind_save,&(ir->opts));
         }
+
         bFirstIterate = TRUE;
-        while (bFirstIterate || (bIterations && iterate.bIterate))
+        while (bFirstIterate || iterate.bIterationActive)
         {
             /* We now restore these vectors to redo the calculation with improved extended variables */    
-            if (bIterations) 
+            if (iterate.bIterationActive)
             { 
                 copy_coupling_state(bufstate,state,ekind_save,ekind,&(ir->opts));
             }
@@ -1618,7 +1626,7 @@ double do_md(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
                 /* UPDATE PRESSURE VARIABLES IN TROTTER FORMULATION WITH CONSTRAINTS */
                 if (bTrotter) 
                 {
-                    if (bIterations && iterate.bIterate) 
+                    if (iterate.bIterationActive)
                     {
                         if (bFirstIterate) 
                         {
@@ -1749,13 +1757,12 @@ double do_md(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
                 wallcycle_stop(wcycle,ewcVSITECONSTR);
             }
             
-            /* ############## IF NOT VV, Calculate globals HERE, also iterate constraints ############ */
+            /* ############## IF NOT VV, Calculate globals HERE, also iterate constraints  ############ */
             /* With Leap-Frog we can skip compute_globals at
              * non-communication steps, but we need to calculate
              * the kinetic energy one step before communication.
              */
-            if (bGStat || do_per_step(step+1,nstglobalcomm) ||
-                EI_VV(ir->eI))
+            if (bGStat || (!EI_VV(ir->eI)&&do_per_step(step+1,nstglobalcomm)))
             {
                 if (ir->nstlist == -1 && bFirstIterate)
                 {
@@ -1774,7 +1781,7 @@ double do_md(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
                                 | (!EI_VV(ir->eI) && bStopCM ? CGLO_STOPCM : 0)
                                 | (!EI_VV(ir->eI) ? CGLO_TEMPERATURE : 0) 
                                 | (!EI_VV(ir->eI) || bRerunMD ? CGLO_PRESSURE : 0) 
-                                | (bIterations && iterate.bIterate ? CGLO_ITERATE : 0) 
+                                | (iterate.bIterationActive ? CGLO_ITERATE : 0)
                                 | (bFirstIterate ? CGLO_FIRSTITERATE : 0)
                                 | CGLO_CONSTRAINT 
                     );
@@ -1792,7 +1799,7 @@ double do_md(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
                but what we actually need entering the new cycle is the new shake_vir value. Ideally, we could
                generate the new shake_vir, but test the veta value for convergence.  This will take some thought. */
 
-            if (bIterations && 
+            if (iterate.bIterationActive &&
                 done_iterating(cr,fplog,step,&iterate,bFirstIterate,
                                trace(shake_vir),&tracevir)) 
             {
diff --git a/src/programs/mdrun/md_openmm.h b/src/programs/mdrun/md_openmm.h
deleted file mode 100644 (file)
index 0cf3172..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
- *
- * 
- *                This source code is part of
- * 
- *                 G   R   O   M   A   C   S
- * 
- *          GROningen MAchine for Chemical Simulations
- * 
- * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2010, The GROMACS development team,
- * check out http://www.gromacs.org for more information.
-
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * 
- * If you want to redistribute modifications, 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 www.gromacs.org.
- * 
- * To help us fund GROMACS development, we humbly ask that you cite
- * the papers on the package - you can find them in the top README file.
- * 
- * For more info, check our website at http://www.gromacs.org
- * 
- * And Hey:
- * Gallium Rubidium Oxygen Manganese Argon Carbon Silicon
- */
-#ifndef _MD_OPENMM_H
-#define _MD_OPENMM_H
-
-double do_md_openmm(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
-             const output_env_t oenv, gmx_bool bVerbose,gmx_bool bCompact,
-             int nstglobalcomm,
-             gmx_vsite_t *vsite,gmx_constr_t constr,
-             int stepout,t_inputrec *ir,
-             gmx_mtop_t *top_global,
-             t_fcdata *fcd,
-             t_state *state_global,
-             t_mdatoms *mdatoms,
-             t_nrnb *nrnb,gmx_wallcycle_t wcycle,
-             gmx_edsam_t ed,t_forcerec *fr,
-             int repl_ex_nst, int repl_ex_nex, int repl_ex_seed,
-             gmx_membed_t membed,
-             real cpt_period,real max_hours,
-             const char *deviceOptions,
-             unsigned long Flags,
-             gmx_runtime_t *runtime);
-
-#endif /* _MD_OPENMM_H */
index 43f9d0112c5ccda13a191df842213a561f784b03..c801a2f684353fc2b231d2da4df1420941dd408b 100644 (file)
 int cmain(int argc,char *argv[])
 {
   const char *desc[] = {
- #ifdef GMX_OPENMM
-    "This is an experimental release of GROMACS for accelerated",
-       "Molecular Dynamics simulations on GPU processors. Support is provided",
-       "by the OpenMM library (https://simtk.org/home/openmm).[PAR]",
-       "*Warning*[BR]",
-       "This release is targeted at developers and advanced users and",
-       "care should be taken before production use. The following should be",
-       "noted before using the program:[PAR]",
-       " * The current release runs only on modern nVidia GPU hardware with CUDA support.",
-       "Make sure that the necessary CUDA drivers and libraries for your operating system",
-       "are already installed. The CUDA SDK also should be installed in order to compile",
-       "the program from source (http://www.nvidia.com/object/cuda_home.html).[PAR]",
-       " * Multiple GPU cards are not supported.[PAR]",
-       " * Only a small subset of the GROMACS features and options are supported on the GPUs.",
-       "See below for a detailed list.[PAR]",
-       " * Consumer level GPU cards are known to often have problems with faulty memory.",
-       "It is recommended that a full memory check of the cards is done at least once",
-       "(for example, using the memtest=full option).",
-       "A partial memory check (for example, memtest=15) before and",
-       "after the simulation run would help spot",
-       "problems resulting from processor overheating.[PAR]",
-       " * The maximum size of the simulated systems depends on the available",
-       "GPU memory,for example, a GTX280 with 1GB memory has been tested with systems",
-       "of up to about 100,000 atoms.[PAR]",
-       " * In order to take a full advantage of the GPU platform features, many algorithms",
-       "have been implemented in a very different way than they are on the CPUs.",
-       "Therefore numercal correspondence between properties of the state of",
-       "simulated systems should not be expected. Moreover, the values will likely vary",
-       "when simulations are done on different GPU hardware.[PAR]",
-       " * Frequent retrieval of system state information such as",
-       "trajectory coordinates and energies can greatly influence the performance",
-       "of the program due to slow CPU<->GPU memory transfer speed.[PAR]",
-       " * MD algorithms are complex, and although the Gromacs code is highly tuned for them,",
-       "they often do not translate very well onto the streaming architetures.",
-       "Realistic expectations about the achievable speed-up from test with GTX280:",
-       "For small protein systems in implicit solvent using all-vs-all kernels the acceleration",
-       "can be as high as 20 times, but in most other setups involving cutoffs and PME the",
-       "acceleration is usually only ~4 times relative to a 3GHz CPU.[PAR]",
-       "Supported features:[PAR]",
-       " * Integrators: md/md-vv/md-vv-avek, sd/sd1 and bd.\n",
-       " * Long-range interactions (option coulombtype): Reaction-Field, Ewald, PME, and cut-off (for Implicit Solvent only)\n",
-       " * Temperature control: Supported only with the md/md-vv/md-vv-avek, sd/sd1 and bd integrators.\n",
-       " * Pressure control: Supported.\n",
-       " * Implicit solvent: Supported.\n",
-       "A detailed description can be found on the GROMACS website:\n",
-       "http://www.gromacs.org/gpu[PAR]",
-/* From the original mdrun documentaion */
-    "The [TT]mdrun[tt] program reads the run input file ([TT]-s[tt])",
-    "and distributes the topology over nodes if needed.",
-    "[TT]mdrun[tt] produces at least four output files.",
-    "A single log file ([TT]-g[tt]) is written, unless the option",
-    "[TT]-seppot[tt] is used, in which case each node writes a log file.",
-    "The trajectory file ([TT]-o[tt]), contains coordinates, velocities and",
-    "optionally forces.",
-    "The structure file ([TT]-c[tt]) contains the coordinates and",
-    "velocities of the last step.",
-    "The energy file ([TT]-e[tt]) contains energies, the temperature,",
-    "pressure, etc, a lot of these things are also printed in the log file.",
-    "Optionally coordinates can be written to a compressed trajectory file",
-    "([TT]-x[tt]).[PAR]",
-/* openmm specific information */
-       "Usage with OpenMM:[BR]",
-       "[TT]mdrun -device \"OpenMM:platform=Cuda,memtest=15,deviceid=0,force-device=no\"[tt][PAR]",
-       "Options:[PAR]",
-       "      [TT]platform[tt] = Cuda\t\t:\tThe only available value. OpenCL support will be available in future.\n",
-       "      [TT]memtest[tt] = 15\t\t:\tRun a partial, random GPU memory test for the given amount of seconds. A full test",
-       "(recommended!) can be run with \"memtest=full\". Memory testing can be disabled with \"memtest=off\".\n",
-       "      [TT]deviceid[tt] = 0\t\t:\tSpecify the target device when multiple cards are present.",
-       "Only one card can be used at any given time though.\n",
-       "      [TT]force-device[tt] = no\t\t:\tIf set to \"yes\" [TT]mdrun[tt]  will be forced to execute on",
-       "hardware that is not officially supported. GPU acceleration can also be achieved on older",
-       "but Cuda capable cards, although the simulation might be too slow, and the memory limits too strict.",
-#else
     "The [TT]mdrun[tt] program is the main computational chemistry engine",
     "within GROMACS. Obviously, it performs Molecular Dynamics simulations,",
     "but it can also perform Stochastic Dynamics, Energy Minimization,",
@@ -314,10 +241,11 @@ int cmain(int argc,char *argv[])
     "forces and energies will be (re)calculated. Neighbor searching will be",
     "performed for every frame, unless [TT]nstlist[tt] is zero",
     "(see the [TT].mdp[tt] file).[PAR]",
-    "ED (essential dynamics) sampling is switched on by using the [TT]-ei[tt]",
-    "flag followed by an [TT].edi[tt] file.",
-    "The [TT].edi[tt] file can be produced using options in the essdyn",
-    "menu of the WHAT IF program. [TT]mdrun[tt] produces a [TT].xvg[tt] output file that",
+    "ED (essential dynamics) sampling and/or additional flooding potentials",
+    "are switched on by using the [TT]-ei[tt] flag followed by an [TT].edi[tt]",
+    "file. The [TT].edi[tt] file can be produced with the [TT]make_edi[tt] tool",
+    "or by using options in the essdyn menu of the WHAT IF program.",
+    "[TT]mdrun[tt] produces a [TT].xvg[tt] output file that",
     "contains projections of positions, velocities and forces onto selected",
     "eigenvectors.[PAR]",
     "When user-defined potential functions have been selected in the",
@@ -427,7 +355,6 @@ int cmain(int argc,char *argv[])
     "the [TT]mdrun[tt] process that is the parent of the others.",
     "[PAR]",
     "When [TT]mdrun[tt] is started with MPI, it does not run niced by default."
-#endif
   };
   t_commrec    *cr;
   t_filenm fnm[] = {
@@ -606,18 +533,13 @@ int cmain(int argc,char *argv[])
       "HIDDENReset cycle counters after these many time steps" },
     { "-resethway", FALSE, etBOOL, {&bResetCountersHalfWay},
       "HIDDENReset the cycle counters after half the number of steps or halfway [TT]-maxh[tt]" }
-#ifdef GMX_OPENMM
-    ,
-    { "-device",  FALSE, etSTR, {&deviceOptions},
-      "Device option string" }
-#endif
   };
   gmx_edsam_t  ed;
   unsigned long Flags, PCA_Flags;
   ivec     ddxyz;
   int      dd_node_order;
   gmx_bool     bAddPart;
-  FILE     *fplog,*fptest;
+  FILE     *fplog,*fpmulti;
   int      sim_part,sim_part_fn;
   const char *part_suffix=".part";
   char     suffix[STRLEN];
@@ -701,7 +623,7 @@ int cmain(int argc,char *argv[])
                                                 &sim_part_fn,NULL,cr,
                                                 bAppendFiles,NFILE,fnm,
                                                 part_suffix,&bAddPart);
-      if (sim_part_fn==0 && MASTER(cr))
+      if (sim_part_fn==0 && MULTIMASTER(cr))
       {
           fprintf(stdout,"No previous checkpoint file present, assuming this is a new run.\n");
       }
@@ -712,7 +634,17 @@ int cmain(int argc,char *argv[])
 
       if (MULTISIM(cr) && MASTER(cr))
       {
-          check_multi_int(stdout,cr->ms,sim_part,"simulation part");
+          if (MULTIMASTER(cr))
+          {
+              /* Log file is not yet available, so if there's a
+               * problem we can only write to stderr. */
+              fpmulti = stderr;
+          }
+          else
+          {
+              fpmulti = NULL;
+          }
+          check_multi_int(fpmulti,cr->ms,sim_part,"simulation part",TRUE);
       }
   } 
   else
@@ -732,7 +664,7 @@ int cmain(int argc,char *argv[])
       sprintf(suffix,"%s%04d",part_suffix,sim_part_fn);
 
       add_suffix_to_output_names(fnm,NFILE,suffix);
-      if (MASTER(cr))
+      if (MULTIMASTER(cr))
       {
           fprintf(stdout,"Checkpoint file is from part %d, new output files will be suffixed '%s'.\n",sim_part-1,suffix);
       }
index 7037c7aa8e0a7f634bef34917b70d225783b0b5f..a079e16a6acf11933c38caf88604e43cd8d14b86 100644 (file)
@@ -1038,10 +1038,6 @@ gmx_membed_t init_membed(FILE *fplog, int nfile, const t_filenm fnm[], gmx_mtop_
             gmx_input("Sorry, parallel g_membed is not yet fully functional.");
         }
 
-#ifdef GMX_OPENMM
-        gmx_input("Sorry, g_membed does not work with openmm.");
-#endif
-
         if(*cpt>=0)
         {
             fprintf(stderr,"\nSetting -cpt to -1, because embedding cannot be restarted from cpt-files.\n");
diff --git a/src/programs/mdrun/openmm_wrapper.h b/src/programs/mdrun/openmm_wrapper.h
deleted file mode 100644 (file)
index 10ea011..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
- *
- * 
- *                This source code is part of
- * 
- *                 G   R   O   M   A   C   S
- * 
- *          GROningen MAchine for Chemical Simulations
- * 
- * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2010, The GROMACS development team,
- * check out http://www.gromacs.org for more information.
-
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * 
- * If you want to redistribute modifications, 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 www.gromacs.org.
- * 
- * To help us fund GROMACS development, we humbly ask that you cite
- * the papers on the package - you can find them in the top README file.
- * 
- * For more info, check our website at http://www.gromacs.org
- * 
- * And Hey:
- * Gallium Rubidium Oxygen Manganese Argon Carbon Silicon
- */
-
-#ifndef _OPENMM_WRAPPER_H_
-#define _OPENMM_WRAPPER_H_
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-#ifdef GMX_OPENMM
-void* openmm_init(FILE *fplog, const char *platformOptStr,
-                    t_inputrec *ir,
-                    gmx_mtop_t *top_global, gmx_localtop_t *top,
-                    t_mdatoms *mdatoms, t_forcerec *fr, t_state *state);
-
-void openmm_take_one_step(void* data);
-
-void openmm_take_steps(void* data, int nsteps);
-
-void openmm_copy_state(void *data,
-                        t_state *state, double *time,
-                        rvec f[], gmx_enerdata_t *enerd,
-                        gmx_bool includePos, gmx_bool includeVel, gmx_bool includeForce, gmx_bool includeEnergy);
-
-void openmm_cleanup(FILE *fplog, void* data);
-#else 
-/* dummy versions of the wrapper functions to enable compilation of 
-   do_md_openmm even when OpenMM is not used */ 
-void* openmm_init(FILE *fplog, const char *platformOptStr,
-                    t_inputrec *ir,
-                    gmx_mtop_t *top_global, gmx_localtop_t *top,
-                    t_mdatoms *mdatoms, t_forcerec *fr, t_state *state){return NULL;}
-
-void openmm_take_one_step(void* data){}
-
-void openmm_take_steps(void* data, int nsteps){}
-
-void openmm_copy_state(void *data,
-                        t_state *state, double *time,
-                        rvec f[], gmx_enerdata_t *enerd,
-                        gmx_bool includePos, gmx_bool includeVel, gmx_bool includeForce, gmx_bool includeEnergy){}
-
-void openmm_cleanup(FILE *fplog, void* data){}
-
-#endif /*GMX_OPENMM*/
-
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif /* _OPENMM_WRAPPER_H_ */
-
index 44559ff4a9321ba3550f356d32ca89efc5fb648a..3fff053d1dae1f9e1f6f339887e9c8e3c9beeae5 100644 (file)
@@ -480,6 +480,23 @@ gmx_bool pme_load_balance(pme_load_balancing_t pme_lb,
     if (set->cycles < pme_lb->setup[pme_lb->fastest].cycles)
     {
         pme_lb->fastest = pme_lb->cur;
+
+        if (DOMAINDECOMP(cr))
+        {
+            /* We found a new fastest setting, ensure that with subsequent
+             * shorter cut-off's the dynamic load balancing does not make
+             * the use of the current cut-off impossible. This solution is
+             * a trade-off, as the PME load balancing and DD domain size
+             * load balancing can interact in complex ways.
+             * With the Verlet kernels, DD load imbalance will usually be
+             * mainly due to bonded interaction imbalance, which will often
+             * quickly push the domain boundaries beyond the limit for the
+             * optimal, PME load balanced, cut-off. But it could be that
+             * better overal performance can be obtained with a slightly
+             * shorter cut-off and better DD load balancing.
+             */
+            change_dd_dlb_cutoff_limit(cr);
+        }
     }
     cycles_fast = pme_lb->setup[pme_lb->fastest].cycles;
 
index fbde22b6e9ac4819f6cd88d392362d13539692ad..a188b8f8ee65fb206936b68e86d2d42e7244b171 100644 (file)
@@ -160,17 +160,17 @@ gmx_repl_ex_t init_replica_exchange(FILE *fplog,
 
     fprintf(fplog,"Repl  There are %d replicas:\n",re->nrepl);
 
-    check_multi_int(fplog,ms,state->natoms,"the number of atoms");
-    check_multi_int(fplog,ms,ir->eI,"the integrator");
-    check_multi_large_int(fplog,ms,ir->init_step+ir->nsteps,"init_step+nsteps");
+    check_multi_int(fplog,ms,state->natoms,"the number of atoms",FALSE);
+    check_multi_int(fplog,ms,ir->eI,"the integrator",FALSE);
+    check_multi_large_int(fplog,ms,ir->init_step+ir->nsteps,"init_step+nsteps",FALSE);
     check_multi_large_int(fplog,ms,(ir->init_step+nst-1)/nst,
-                          "first exchange step: init_step/-replex");
-    check_multi_int(fplog,ms,ir->etc,"the temperature coupling");
+                          "first exchange step: init_step/-replex",FALSE);
+    check_multi_int(fplog,ms,ir->etc,"the temperature coupling",FALSE);
     check_multi_int(fplog,ms,ir->opts.ngtc,
-                    "the number of temperature coupling groups");
-    check_multi_int(fplog,ms,ir->epc,"the pressure coupling");
-    check_multi_int(fplog,ms,ir->efep,"free energy");
-    check_multi_int(fplog,ms,ir->fepvals->n_lambda,"number of lambda states");
+                    "the number of temperature coupling groups",FALSE);
+    check_multi_int(fplog,ms,ir->epc,"the pressure coupling",FALSE);
+    check_multi_int(fplog,ms,ir->efep,"free energy",FALSE);
+    check_multi_int(fplog,ms,ir->fepvals->n_lambda,"number of lambda states",FALSE);
 
     re->temp = ir->opts.ref_t[0];
     for(i=1; (i<ir->opts.ngtc); i++)
index 86db8f722534ce8ec808b8ff59db8c6dde2a3f28..40b48cd6914f1679bfd31959a783fa7cce749660 100644 (file)
 #include "corewrap.h"
 #endif
 
-#ifdef GMX_OPENMM
-#include "md_openmm.h"
-#endif
-
 #include "gpu_utils.h"
 #include "nbnxn_cuda_data_mgmt.h"
 
@@ -112,11 +108,7 @@ typedef struct {
 } gmx_intp_t;
 
 /* The array should match the eI array in include/types/enums.h */
-#ifdef GMX_OPENMM  /* FIXME do_md_openmm needs fixing */
-const gmx_intp_t integrator[eiNR] = { {do_md_openmm}, {do_md_openmm}, {do_md_openmm}, {do_md_openmm}, {do_md_openmm}, {do_md_openmm}, {do_md_openmm}, {do_md_openmm}, {do_md_openmm}, {do_md_openmm}, {do_md_openmm},{do_md_openmm}};
-#else
 const gmx_intp_t integrator[eiNR] = { {do_md}, {do_steep}, {do_cg}, {do_md}, {do_md}, {do_nm}, {do_lbfgs}, {do_tpi}, {do_tpi}, {do_md}, {do_md},{do_md}};
-#endif
 
 gmx_large_int_t     deform_init_init_step_tpx;
 matrix              deform_init_box_tpx;
@@ -1080,9 +1072,10 @@ static void set_cpu_affinity(FILE *fplog,
 
 
 static void check_and_update_hw_opt(gmx_hw_opt_t *hw_opt,
-                                    int cutoff_scheme)
+                                    int cutoff_scheme,
+                                    gmx_bool bIsSimMaster)
 {
-    gmx_omp_nthreads_read_env(&hw_opt->nthreads_omp);
+    gmx_omp_nthreads_read_env(&hw_opt->nthreads_omp, bIsSimMaster);
 
 #ifndef GMX_THREAD_MPI
     if (hw_opt->nthreads_tot > 0)
@@ -1343,7 +1336,7 @@ int mdrunner(gmx_hw_opt_t *hw_opt,
     if (SIMMASTER(cr))
 #endif
     {
-        check_and_update_hw_opt(hw_opt,minf.cutoff_scheme);
+        check_and_update_hw_opt(hw_opt,minf.cutoff_scheme,SIMMASTER(cr));
 
 #ifdef GMX_THREAD_MPI
         /* Early check for externally set process affinity. Can't do over all
@@ -1530,7 +1523,7 @@ int mdrunner(gmx_hw_opt_t *hw_opt,
     snew(fcd,1);
 
     /* This needs to be called before read_checkpoint to extend the state */
-    init_disres(fplog,mtop,inputrec,cr,Flags & MD_PARTDEC,fcd,state);
+    init_disres(fplog,mtop,inputrec,cr,Flags & MD_PARTDEC,fcd,state, repl_ex_nst > 0);
 
     if (gmx_mtop_ftype_count(mtop,F_ORIRES) > 0)
     {
@@ -1848,12 +1841,7 @@ int mdrunner(gmx_hw_opt_t *hw_opt,
     }
 
 
-    if (integrator[inputrec->eI].func == do_md
-#ifdef GMX_OPENMM
-        ||
-        integrator[inputrec->eI].func == do_md_openmm
-#endif
-        )
+    if (integrator[inputrec->eI].func == do_md)
     {
         /* Turn on signal handling on all nodes */
         /*
index 727174b371c2328f8068820254f46f39d21307e2..41a1eb0b83ece74e32703ff0ef1037965f3677e7 100644 (file)
 #include "gmx_ana.h"
 #include "maths.h"
 #include "string2.h"
+#include "names.h"
+#include "mdebin.h"
 
-/* the dhdl.xvg data from a simulation (actually obsolete, but still
-    here for reading the dhdl.xvg file*/
+
+/* Structure for the names of lambda vector components */
+typedef struct lambda_components_t
+{
+    char **names; /* Array of strings with names for the lambda vector
+                     components */
+    int N;              /* The number of components */
+    int Nalloc;         /* The number of allocated components */
+} lambda_components_t;
+
+/* Structure for a lambda vector or a dhdl derivative direction */
+typedef struct lambda_vec_t
+{
+    double *val;    /* The lambda vector component values. Only valid if
+                       dhdl == -1 */
+    int dhdl;       /* The coordinate index for the derivative described by this
+                       structure, or -1 */
+    const lambda_components_t *lc; /* the associated lambda_components
+                                      structure */
+    int index;      /* The state number (init-lambda-state) of this lambda
+                       vector, if known. If not, it is set to -1 */
+} lambda_vec_t;
+
+/* the dhdl.xvg data from a simulation */
 typedef struct xvg_t
 {
-    char   *filename;
+    const char   *filename;
     int    ftp;     /* file type */
     int    nset;    /* number of lambdas, including dhdl */
     int *np;        /* number of data points (du or hists) per lambda */
     int  np_alloc;  /* number of points (du or hists) allocated */
     double temp;    /* temperature */
-    double *lambda; /* the lambdas (of first index for y). */
+    lambda_vec_t *lambda; /* the lambdas (of first index for y). */
     double *t;      /* the times (of second index for y) */
     double **y;     /* the dU values. y[0] holds the derivative, while
                        further ones contain the energy differences between
                        the native lambda and the 'foreign' lambdas. */
-
-    double native_lambda; /* the native lambda */
+    lambda_vec_t native_lambda; /* the native lambda */
 
     struct xvg_t *next, *prev; /*location in the global linked list of xvg_ts*/
 } xvg_t;
 
 
-
 typedef struct hist_t
 {
     unsigned int *bin[2];       /* the (forward + reverse) histogram values */
@@ -101,8 +123,8 @@ typedef struct hist_t
 /* an aggregate of samples for partial free energy calculation */
 typedef struct samples_t 
 {    
-    double native_lambda; 
-    double foreign_lambda;
+    lambda_vec_t *native_lambda;  /* pointer to native lambda vector */
+    lambda_vec_t *foreign_lambda; /* pointer to foreign lambda vector */
     double temp; /* the temperature */
     gmx_bool derivative; /* whether this sample is a derivative */
 
@@ -140,8 +162,9 @@ typedef struct sample_range_t
     foreign lambda) */
 typedef struct sample_coll_t
 {
-    double native_lambda;  /* these should be the same for all samples in the histogram?*/
-    double foreign_lambda; /* collection */
+    lambda_vec_t *native_lambda;  /* these should be the same for all samples
+                                     in the histogram */
+    lambda_vec_t *foreign_lambda; /* collection */
     double temp; /* the temperature */
 
     int nsamples; /* the number of samples */
@@ -156,20 +179,29 @@ typedef struct sample_coll_t
 } sample_coll_t;
 
 /* all the samples associated with a lambda point */
-typedef struct lambda_t
+typedef struct lambda_data_t
 {
-    double lambda; /* the native lambda (at start time if dynamic) */
+    lambda_vec_t *lambda; /* the native lambda (at start time if dynamic) */
     double temp; /* temperature */
 
     sample_coll_t *sc; /* the samples */
 
     sample_coll_t sc_head; /*the pre-allocated list head for the linked list.*/
 
-    struct lambda_t *next, *prev; /* the next and prev in the list */
-} lambda_t;
+    struct lambda_data_t *next, *prev; /* the next and prev in the list */
+} lambda_data_t;
+
+/* Top-level data structure of simulation data */
+typedef struct sim_data_t
+{
+    lambda_data_t *lb; /* a lambda data linked list */
+    lambda_data_t lb_head; /* The head element of the linked list */
 
+    lambda_components_t lc; /* the allowed components of the lambda
+                               vectors */
+} sim_data_t;
 
-/* calculated values. */
+/* Top-level data structure with calculated values. */
 typedef struct {
     sample_coll_t *a, *b; /* the simulation data */
 
@@ -189,6 +221,350 @@ typedef struct {
 } barres_t;
 
 
+/* Initialize a lambda_components structure */
+static void lambda_components_init(lambda_components_t *lc)
+{
+    lc->N=0;
+    lc->Nalloc=2;
+    snew(lc->names, lc->Nalloc);
+}
+
+/* Add a component to a lambda_components structure */
+static void lambda_components_add(lambda_components_t *lc,
+                                  const char *name, size_t name_length)
+{
+    while (lc->N + 1 > lc->Nalloc)
+    {
+        lc->Nalloc = (lc->Nalloc == 0) ? 2 : 2*lc->Nalloc;
+        srealloc( lc->names, lc->Nalloc );
+    }
+    snew(lc->names[lc->N], name_length+1);
+    strncpy(lc->names[lc->N], name, name_length);
+    lc->N++;
+}
+
+/* check whether a component with index 'index' matches the given name, or
+   is also NULL. Returns TRUE if this is the case.
+   the string name does not need to end */
+static gmx_bool lambda_components_check(const lambda_components_t *lc,
+                                        int index,
+                                        const char *name,
+                                        size_t name_length)
+{
+    size_t len;
+    if (index >= lc->N)
+        return FALSE;
+    if (name == NULL && lc->names[index] == NULL)
+        return TRUE;
+    if ((name == NULL) != (lc->names[index] == NULL))
+        return FALSE;
+    len = strlen(lc->names[index]);
+    if (len != name_length)
+        return FALSE;
+    if (strncmp(lc->names[index], name, name_length)== 0)
+        return TRUE;
+    return FALSE;
+}
+
+/* Find the index of a given lambda component name, or -1 if not found */
+static int lambda_components_find(const lambda_components_t *lc,
+                                  const char *name,
+                                  size_t name_length)
+{
+    int i;
+
+    for(i=0;i<lc->N;i++)
+    {
+        if (strncmp(lc->names[i], name, name_length) == 0)
+            return i;
+    }
+    return -1;
+}
+
+
+
+/* initialize a lambda vector */
+static void lambda_vec_init(lambda_vec_t *lv, const lambda_components_t *lc)
+{
+    snew(lv->val, lc->N);
+    lv->index = -1;
+    lv->dhdl = -1;
+    lv->lc = lc;
+}
+
+static void lambda_vec_destroy(lambda_vec_t *lv)
+{
+    sfree(lv->val);
+}
+
+static void lambda_vec_copy(lambda_vec_t *lv, const lambda_vec_t *orig)
+{
+    int i;
+
+    lambda_vec_init(lv, orig->lc);
+    lv->dhdl=orig->dhdl;
+    lv->index=orig->index;
+    for(i=0;i<lv->lc->N;i++)
+    {
+        lv->val[i] = orig->val[i];
+    }
+}
+
+/* write a lambda vec to a preallocated string */
+static void lambda_vec_print(const lambda_vec_t *lv, char *str, gmx_bool named)
+{
+    int i;
+    size_t np;
+
+    str[0]=0; /* reset the string */
+    if (lv -> dhdl < 0)
+    {
+        if (named)
+        {
+            str += sprintf(str, "delta H to ");
+        }
+        if (lv->lc->N > 1)
+        {
+            str += sprintf(str, "(");
+        }
+        for(i=0;i<lv->lc->N;i++)
+        {
+            str += sprintf(str, "%g", lv->val[i]);
+            if (i < lv->lc->N-1)
+            {
+                str += sprintf(str, ", ");
+            }
+        }
+        if (lv->lc->N > 1)
+        {
+            str += sprintf(str, ")");
+        }
+    }
+    else
+    {
+        /* this lambda vector describes a derivative */
+        str += sprintf(str, "dH/dl");
+        if (strlen(lv->lc->names[lv->dhdl]) > 0)
+        {
+            str += sprintf(str, " (%s)", lv->lc->names[lv->dhdl]);
+        }
+    }
+}
+
+/* write a shortened version of the lambda vec to a preallocated string */
+static void lambda_vec_print_short(const lambda_vec_t *lv, char *str)
+{
+    int i;
+    size_t np;
+
+    if (lv->index >= 0)
+    {
+        sprintf(str, "%6d", lv->index);
+    }
+    else
+    {
+        if (lv->dhdl < 0)
+        {
+            sprintf(str, "%6.3f", lv->val[0]);
+        }
+        else
+        {
+            sprintf(str, "dH/dl[%d]", lv->dhdl);
+        }
+    }
+}
+
+/* write an intermediate version of two lambda vecs to a preallocated string */
+static void lambda_vec_print_intermediate(const lambda_vec_t *a,
+                                          const lambda_vec_t *b, char *str)
+{
+    int i;
+    size_t np;
+
+    str[0]=0;
+    if ( (a->index >= 0) && (b->index>=0) )
+    {
+        sprintf(str, "%6.3f", ((double)a->index+(double)b->index)/2.);
+    }
+    else
+    {
+        if ( (a->dhdl < 0) && (b->dhdl < 0) )
+        {
+            sprintf(str, "%6.3f", (a->val[0]+b->val[0])/2.);
+        }
+    }
+}
+
+
+
+/* calculate the difference in lambda vectors: c = a-b.
+   c must be initialized already, and a and b must describe non-derivative
+   lambda points */
+static void lambda_vec_diff(const lambda_vec_t *a, const lambda_vec_t *b,
+                            lambda_vec_t *c)
+{
+    int i;
+
+    if ( (a->dhdl > 0)  || (b->dhdl > 0) )
+    {
+        gmx_fatal(FARGS,
+                  "Trying to calculate the difference between derivatives instead of lambda points");
+    }
+    if ((a->lc != b->lc) || (a->lc != c->lc) )
+    {
+        gmx_fatal(FARGS,
+                  "Trying to calculate the difference lambdas with differing basis set");
+    }
+    for(i=0;i<a->lc->N;i++)
+    {
+        c->val[i] = a->val[i] - b->val[i];
+    }
+}
+
+/* calculate and return the absolute difference in lambda vectors: c = |a-b|. 
+   a and b must describe non-derivative lambda points */
+static double lambda_vec_abs_diff(const lambda_vec_t *a, const lambda_vec_t *b)
+{
+    int i;
+    double ret=0.;
+
+    if ( (a->dhdl > 0)  || (b->dhdl > 0) )
+    {
+        gmx_fatal(FARGS,
+                  "Trying to calculate the difference between derivatives instead of lambda points");
+    }
+    if (a->lc != b->lc) 
+    {
+        gmx_fatal(FARGS,
+                  "Trying to calculate the difference lambdas with differing basis set");
+    }
+    for(i=0;i<a->lc->N;i++)
+    {
+        double df=a->val[i] - b->val[i];
+        ret += df*df;
+    }
+    return sqrt(ret);
+}
+
+
+/* check whether two lambda vectors are the same */
+static gmx_bool lambda_vec_same(const lambda_vec_t *a, const lambda_vec_t *b)
+{
+    int i;
+
+    if (a->lc != b->lc)
+        return FALSE;
+    if (a->dhdl < 0)
+    {
+        for(i=0;i<a->lc->N;i++)
+        {
+            if (!gmx_within_tol(a->val[i], b->val[i], 10*GMX_REAL_EPS))
+            {
+                return FALSE;
+            }
+        }
+        return TRUE;
+    }
+    else
+    {
+        /* they're derivatives, so we check whether the indices match */
+        return (a->dhdl == b->dhdl);
+    }
+}
+
+/* Compare the sort order of two foreign lambda vectors
+
+    returns 1 if a is 'bigger' than b,
+    returns 0 if they're the same,
+    returns -1 if a is 'smaller' than b.*/
+static gmx_bool lambda_vec_cmp_foreign(const lambda_vec_t *a,
+                                       const lambda_vec_t *b)
+{
+    int i;
+    double norm_a=0, norm_b=0;
+    gmx_bool different=FALSE;
+
+    if (a->lc != b->lc)
+    {
+        gmx_fatal(FARGS, "Can't compare lambdas with differing basis sets");
+    }
+    /* if either one has an index we sort based on that */
+    if ((a->index >= 0) || (b->index >= 0))
+    {
+        if (a->index == b->index)
+            return 0;
+        return (a->index > b->index) ? 1 : -1;
+    }
+    if (a->dhdl >= 0 || b->dhdl >= 0)
+    {
+        /* lambda vectors that are derivatives always sort higher than those
+           without derivatives */
+        if ((a->dhdl >= 0)  != (b->dhdl >= 0) )
+        {
+            return (a->dhdl >= 0) ? 1 : -1 ;
+        }
+        return a->dhdl > b->dhdl;
+    }
+
+    /* neither has an index, so we can only sort on the lambda components,
+       which is only valid if there is one component */
+    for(i=0;i<a->lc->N;i++)
+    {
+        if (!gmx_within_tol(a->val[i], b->val[i], 10*GMX_REAL_EPS))
+        {
+            different=TRUE;
+        }
+        norm_a += a->val[i]*a->val[i];
+        norm_b += b->val[i]*b->val[i];
+    }
+    if (!different)
+    {
+        return 0;
+    }
+    return norm_a > norm_b;
+}
+
+/* Compare the sort order of two native lambda vectors
+
+    returns 1 if a is 'bigger' than b,
+    returns 0 if they're the same,
+    returns -1 if a is 'smaller' than b.*/
+static gmx_bool lambda_vec_cmp_native(const lambda_vec_t *a,
+                                      const lambda_vec_t *b)
+{
+    int i;
+
+    if (a->lc != b->lc)
+    {
+        gmx_fatal(FARGS, "Can't compare lambdas with differing basis sets");
+    }
+    /* if either one has an index we sort based on that */
+    if ((a->index >= 0) || (b->index >= 0))
+    {
+        if (a->index == b->index)
+            return 0;
+        return (a->index > b->index) ? 1 : -1;
+    }
+    /* neither has an index, so we can only sort on the lambda components,
+       which is only valid if there is one component */
+    if (a->lc->N > 1)
+    {
+        gmx_fatal(FARGS,
+                  "Can't compare lambdas with no index and > 1 component");
+    }
+    if (a->dhdl >= 0 || b->dhdl >= 0)
+    {
+        gmx_fatal(FARGS,
+                  "Can't compare native lambdas that are derivatives");
+    }
+    if (gmx_within_tol(a->val[0], b->val[0], 10*GMX_REAL_EPS))
+    {
+        return 0;
+    }
+    return a->val[0] > b->val[0] ? 1 : -1;
+}
+
+
 
 
 static void hist_init(hist_t *h, int nhist, int *nbin)
@@ -225,8 +601,8 @@ static void xvg_init(xvg_t *ba)
     ba->y=NULL;
 }
 
-static void samples_init(samples_t *s, double native_lambda,
-                         double foreign_lambda, double temp,
+static void samples_init(samples_t *s, lambda_vec_t *native_lambda,
+                         lambda_vec_t *foreign_lambda, double temp,
                          gmx_bool derivative, const char *filename)
 {
     s->native_lambda=native_lambda;
@@ -257,8 +633,8 @@ static void sample_range_init(sample_range_t *r, samples_t *s)
     r->s=NULL;
 }
 
-static void sample_coll_init(sample_coll_t *sc, double native_lambda,
-                             double foreign_lambda, double temp)
+static void sample_coll_init(sample_coll_t *sc, lambda_vec_t *native_lambda,
+                             lambda_vec_t *foreign_lambda, double temp)
 {
     sc->native_lambda = native_lambda;
     sc->foreign_lambda = foreign_lambda;
@@ -281,7 +657,8 @@ static void sample_coll_destroy(sample_coll_t *sc)
 }
 
 
-static void lambda_init(lambda_t *l, double native_lambda, double temp)
+static void lambda_data_init(lambda_data_t *l, lambda_vec_t *native_lambda,
+                             double temp)
 {
     l->lambda=native_lambda;
     l->temp=temp;
@@ -291,7 +668,7 @@ static void lambda_init(lambda_t *l, double native_lambda, double temp)
 
     l->sc=&(l->sc_head);
 
-    sample_coll_init(l->sc, native_lambda, 0., 0.);
+    sample_coll_init(l->sc, native_lambda, NULL, 0.);
     l->sc->next=l->sc;
     l->sc->prev=l->sc;
 }
@@ -312,13 +689,6 @@ static void barres_init(barres_t *br)
 }
 
 
-
-
-static gmx_bool lambda_same(double lambda1, double lambda2)
-{
-    return gmx_within_tol(lambda1, lambda2, 10*GMX_REAL_EPS);
-}
-
 /* calculate the total number of samples in a sample collection */
 static void sample_coll_calc_ntot(sample_coll_t *sc)
 {
@@ -344,14 +714,14 @@ static void sample_coll_calc_ntot(sample_coll_t *sc)
 
 /* find the barsamples_t associated with a lambda that corresponds to
    a specific foreign lambda */
-static sample_coll_t *lambda_find_sample_coll(lambda_t *l, 
-                                              double foreign_lambda)
+static sample_coll_t *lambda_data_find_sample_coll(lambda_data_t *l,
+                                                   lambda_vec_t *foreign_lambda)
 {
     sample_coll_t *sc=l->sc->next;
 
     while(sc != l->sc)
     {
-        if (lambda_same(sc->foreign_lambda,foreign_lambda))
+        if (lambda_vec_same(sc->foreign_lambda,foreign_lambda))
         {
             return sc;
         }
@@ -362,12 +732,12 @@ static sample_coll_t *lambda_find_sample_coll(lambda_t *l,
 }
 
 /* insert li into an ordered list of lambda_colls */
-static void lambda_insert_sample_coll(lambda_t *l, sample_coll_t *sc)
+static void lambda_data_insert_sample_coll(lambda_data_t *l, sample_coll_t *sc)
 {
     sample_coll_t *scn=l->sc->next;
     while ( (scn!=l->sc) )
     {
-        if (scn->foreign_lambda > sc->foreign_lambda)
+        if (lambda_vec_cmp_foreign(scn->foreign_lambda, sc->foreign_lambda) > 0)
             break;
         scn=scn->next;
     }
@@ -379,12 +749,12 @@ static void lambda_insert_sample_coll(lambda_t *l, sample_coll_t *sc)
 }
 
 /* insert li into an ordered list of lambdas */
-static void lambda_insert_lambda(lambda_t *head, lambda_t *li)
+static void lambda_data_insert_lambda(lambda_data_t *head, lambda_data_t *li)
 {
-    lambda_t *lc=head->next;
+    lambda_data_t *lc=head->next;
     while (lc!=head) 
     {
-        if (lc->lambda > li->lambda)
+        if (lambda_vec_cmp_native(lc->lambda, li->lambda) > 0)
             break;
         lc=lc->next;
     }
@@ -406,12 +776,12 @@ static void sample_coll_insert_sample(sample_coll_t *sc, samples_t *s,
         gmx_fatal(FARGS, "Temperatures in files %s and %s are not the same!",
                    s->filename, sc->next->s[0]->filename);
     }
-    if (sc->native_lambda != s->native_lambda)
+    if (!lambda_vec_same(sc->native_lambda, s->native_lambda))
     {
         gmx_fatal(FARGS, "Native lambda in files %s and %s are not the same (and they should be)!",
                    s->filename, sc->next->s[0]->filename);
     }
-    if (sc->foreign_lambda != s->foreign_lambda)
+    if (!lambda_vec_same(sc->foreign_lambda,s->foreign_lambda))
     {
         gmx_fatal(FARGS, "Foreign lambda in files %s and %s are not the same (and they should be)!",
                    s->filename, sc->next->s[0]->filename);
@@ -433,18 +803,18 @@ static void sample_coll_insert_sample(sample_coll_t *sc, samples_t *s,
 
 /* insert a sample into a lambda_list, creating the right sample_coll if 
    neccesary */
-static void lambda_list_insert_sample(lambda_t *head, samples_t *s)
+static void lambda_data_list_insert_sample(lambda_data_t *head, samples_t *s)
 {
     gmx_bool found=FALSE;
     sample_coll_t *sc;
     sample_range_t r;
 
-    lambda_t *l=head->next;
+    lambda_data_t *l=head->next;
 
-    /* first search for the right lambda_t */
+    /* first search for the right lambda_data_t */
     while(l != head)
     {
-        if (lambda_same(l->lambda, s->native_lambda) )
+        if (lambda_vec_same(l->lambda, s->native_lambda) )
         {
             found=TRUE;
             break;
@@ -455,17 +825,17 @@ static void lambda_list_insert_sample(lambda_t *head, samples_t *s)
     if (!found)
     {
         snew(l, 1); /* allocate a new one */
-        lambda_init(l, s->native_lambda, s->temp); /* initialize it */
-        lambda_insert_lambda(head, l); /* add it to the list */
+        lambda_data_init(l, s->native_lambda, s->temp); /* initialize it */
+        lambda_data_insert_lambda(head, l); /* add it to the list */
     }
 
     /* now look for a sample collection */
-    sc=lambda_find_sample_coll(l, s->foreign_lambda);
+    sc=lambda_data_find_sample_coll(l, s->foreign_lambda);
     if (!sc)
     {
         snew(sc, 1); /* allocate a new one */
         sample_coll_init(sc, s->native_lambda, s->foreign_lambda, s->temp);
-        lambda_insert_sample_coll(l, sc);
+        lambda_data_insert_sample_coll(l, sc);
     }
 
     /* now insert the samples into the sample coll */
@@ -629,15 +999,15 @@ static void sample_coll_make_hist(sample_coll_t *sc, int **bin,
 }
 
 /* write a collection of histograms to a file */
-void lambdas_histogram(lambda_t *bl_head, const char *filename, 
-                       int nbin_default, const output_env_t oenv)
+void sim_data_histogram(sim_data_t *sd, const char *filename,
+                        int nbin_default, const output_env_t oenv)
 {
     char label_x[STRLEN];
     const char *dhdl="dH/d\\lambda",*deltag="\\DeltaH",*lambda="\\lambda";
     const char *title="N(\\DeltaH)";
     const char *label_y="Samples";
     FILE *fp;
-    lambda_t *bl;
+    lambda_data_t *bl;
     int nsets=0;
     char **setnames=NULL;
     gmx_bool first_set=FALSE;
@@ -648,6 +1018,7 @@ void lambdas_histogram(lambda_t *bl_head, const char *filename,
     double dx=0;
     double min=0;
     int i;
+    lambda_data_t *bl_head = sd->lb;
 
     printf("\nWriting histogram to %s\n", filename);
     sprintf(label_x, "\\DeltaH (%s)", unit_energy);
@@ -664,19 +1035,23 @@ void lambdas_histogram(lambda_t *bl_head, const char *filename,
         /* iterate over all samples */
         while(sc!=bl->sc)
         {
+            char buf[STRLEN], buf2[STRLEN];
+
             nsets++;
             srenew(setnames, nsets); 
             snew(setnames[nsets-1], STRLEN);
-            if (!lambda_same(sc->foreign_lambda, sc->native_lambda))
+            if (sc->foreign_lambda->dhdl < 0)
             {
-                sprintf(setnames[nsets-1], "N(%s(%s=%g) | %s=%g)",
-                        deltag, lambda, sc->foreign_lambda, lambda,
-                        sc->native_lambda);
+                lambda_vec_print(sc->native_lambda, buf, FALSE);
+                lambda_vec_print(sc->foreign_lambda, buf2, FALSE);
+                sprintf(setnames[nsets-1], "N(%s(%s=%s) | %s=%s)",
+                        deltag, lambda, buf2, lambda, buf);
             }
             else
             {
-                sprintf(setnames[nsets-1], "N(%s | %s=%g)",
-                        dhdl, lambda, sc->native_lambda);
+                lambda_vec_print(sc->native_lambda, buf, FALSE);
+                sprintf(setnames[nsets-1], "N(%s | %s=%s)",
+                        dhdl, lambda, buf);
             }
             sc=sc->next;
         }
@@ -727,15 +1102,16 @@ void lambdas_histogram(lambda_t *bl_head, const char *filename,
 
 /* create a collection (array) of barres_t object given a ordered linked list 
    of barlamda_t sample collections */
-static barres_t *barres_list_create(lambda_t *bl_head, int *nres,
+static barres_t *barres_list_create(sim_data_t *sd, int *nres,
                                     gmx_bool use_dhdl)
 {
-    lambda_t *bl;
+    lambda_data_t *bl;
     int nlambda=0;
     barres_t *res;
     int i;
     gmx_bool dhdl=FALSE;
     gmx_bool first=TRUE;
+    lambda_data_t *bl_head=sd->lb;
 
     /* first count the lambdas */
     bl=bl_head->next;
@@ -755,8 +1131,8 @@ static barres_t *barres_list_create(lambda_t *bl_head, int *nres,
         barres_t *br=&(res[*nres]);
         /* there is always a previous one. we search for that as a foreign 
            lambda: */
-        scprev=lambda_find_sample_coll(bl->prev, bl->lambda);
-        sc=lambda_find_sample_coll(bl, bl->prev->lambda);
+        scprev=lambda_data_find_sample_coll(bl->prev, bl->lambda);
+        sc=lambda_data_find_sample_coll(bl, bl->prev->lambda);
 
         barres_init(br);
 
@@ -764,8 +1140,8 @@ static barres_t *barres_list_create(lambda_t *bl_head, int *nres,
         {
             /* we use dhdl */
 
-            scprev=lambda_find_sample_coll(bl->prev, bl->prev->lambda);
-            sc=lambda_find_sample_coll(bl, bl->lambda);
+            scprev=lambda_data_find_sample_coll(bl->prev, bl->prev->lambda);
+            sc=lambda_data_find_sample_coll(bl, bl->lambda);
 
             if (first)
             {
@@ -812,7 +1188,8 @@ static double barres_list_max_disc_err(barres_t *res, int nres)
     {
         barres_t *br=&(res[i]);
 
-        delta_lambda=fabs(br->b->native_lambda-br->a->native_lambda);
+        delta_lambda=lambda_vec_abs_diff(br->b->native_lambda,
+                                         br->a->native_lambda);
 
         for(j=0;j<br->a->nsamples;j++)
         {
@@ -899,11 +1276,12 @@ static void sample_coll_impose_times(sample_coll_t *sc, double begin_t,
     sample_coll_calc_ntot(sc);
 }
 
-static void lambdas_impose_times(lambda_t *head, double begin, double end)
+static void sim_data_impose_times(sim_data_t *sd, double begin, double end)
 {
     double first_t, last_t;
     double begin_t, end_t;
-    lambda_t *lc;
+    lambda_data_t *lc;
+    lambda_data_t *head=sd->lb;
     int j;
 
     if (begin<=0 && end<0) 
@@ -1169,6 +1547,17 @@ static void sample_coll_min_max(sample_coll_t *sc, double Wfac,
     }
 }
 
+/* Initialize a sim_data structure */
+static void sim_data_init(sim_data_t *sd)
+{
+    /* make linked list */
+    sd->lb = &(sd->lb_head);
+    sd->lb->next = sd->lb;
+    sd->lb->prev = sd->lb;
+
+    lambda_components_init(&(sd->lc));
+}
+
 
 static double calc_bar_sum(int n,const double *W,double Wfac,double sbMmDG)
 {
@@ -1244,7 +1633,8 @@ static double calc_bar_lowlevel(sample_coll_t *ca, sample_coll_t *cb,
 
     M = log(n1/n2);
 
-    if (!lambda_same(ca->native_lambda, ca->foreign_lambda))
+    /*if (!lambda_vec_same(ca->native_lambda, ca->foreign_lambda))*/
+    if (ca->foreign_lambda->dhdl<0)
     {
         /* this is the case when the delta U were calculated directly
            (i.e. we're not scaling dhdl) */
@@ -1255,7 +1645,15 @@ static double calc_bar_lowlevel(sample_coll_t *ca, sample_coll_t *cb,
     {
         /* we're using dhdl, so delta_lambda needs to be a 
            multiplication factor.  */
-        double delta_lambda=cb->native_lambda-ca->native_lambda;
+        /*double delta_lambda=cb->native_lambda-ca->native_lambda;*/
+        double delta_lambda=lambda_vec_abs_diff(cb->native_lambda,
+                                                ca->native_lambda);
+        if (cb->native_lambda->lc->N > 1)
+        {
+            gmx_fatal(FARGS,
+                      "Can't (yet) do multi-component dhdl interpolation");
+        }
+
         Wfac1 =  beta*delta_lambda;
         Wfac2 = -beta*delta_lambda;
     }
@@ -1373,7 +1771,8 @@ static void calc_rel_entropy(sample_coll_t *ca, sample_coll_t *cb,
     n2 = cb->ntot;
 
     /* to ensure the work values are the same as during the delta_G */
-    if (!lambda_same(ca->native_lambda, ca->foreign_lambda))
+    /*if (!lambda_vec_same(ca->native_lambda, ca->foreign_lambda))*/
+    if (ca->foreign_lambda->dhdl<0)
     {
         /* this is the case when the delta U were calculated directly
            (i.e. we're not scaling dhdl) */
@@ -1384,7 +1783,8 @@ static void calc_rel_entropy(sample_coll_t *ca, sample_coll_t *cb,
     {
         /* we're using dhdl, so delta_lambda needs to be a 
            multiplication factor.  */
-        double delta_lambda=cb->native_lambda-ca->native_lambda;
+        double delta_lambda=lambda_vec_abs_diff(cb->native_lambda,
+                                                ca->native_lambda);
         Wfac1 =  beta*delta_lambda;
         Wfac2 = -beta*delta_lambda;
     }
@@ -1483,7 +1883,8 @@ static void calc_dg_stddev(sample_coll_t *ca, sample_coll_t *cb,
     n2 = cb->ntot;
 
     /* to ensure the work values are the same as during the delta_G */
-    if (!lambda_same(ca->native_lambda, ca->foreign_lambda))
+    /*if (!lambda_vec_same(ca->native_lambda, ca->foreign_lambda))*/
+    if (ca->foreign_lambda->dhdl<0)
     {
         /* this is the case when the delta U were calculated directly
            (i.e. we're not scaling dhdl) */
@@ -1494,7 +1895,8 @@ static void calc_dg_stddev(sample_coll_t *ca, sample_coll_t *cb,
     {
         /* we're using dhdl, so delta_lambda needs to be a 
            multiplication factor.  */
-        double delta_lambda=cb->native_lambda-ca->native_lambda;
+        double delta_lambda=lambda_vec_abs_diff(cb->native_lambda,
+                                                ca->native_lambda);
         Wfac1 =  beta*delta_lambda;
         Wfac2 = -beta*delta_lambda;
     }
@@ -1767,43 +2169,274 @@ static double bar_err(int nbmin, int nbmax, const double *partsum)
     return sqrt(svar/(nbmax + 1 - nbmin));
 }
 
+
+/* Seek the end of an identifier (consecutive non-spaces), followed by
+   an optional number of spaces or '='-signs. Returns a pointer to the
+   first non-space value found after that. Returns NULL if the string
+   ends before that.
+   */
+static const char *find_value(const char *str)
+{
+    gmx_bool name_end_found=FALSE;
+
+    /* if the string is a NULL pointer, return a NULL pointer. */
+    if (str==NULL)
+    {
+        return NULL;
+    }
+    while(*str != '\0')
+    {
+        /* first find the end of the name */
+        if (! name_end_found)
+        {
+            if ( isspace(*str) || (*str == '=') )
+            {
+                name_end_found=TRUE;
+            }
+        }
+        else
+        {
+            if (! ( isspace(*str) || (*str == '=') ))
+            {
+                return str;
+            }
+        }
+        str++;
+    }
+    return NULL;
+}
+
+
+
+/* read a vector-notation description of a lambda vector */
+static gmx_bool read_lambda_compvec(const char *str,
+                                    lambda_vec_t *lv,
+                                    const lambda_components_t *lc_in,
+                                    lambda_components_t *lc_out,
+                                    const char **end,
+                                    const char *fn)
+{
+    gmx_bool initialize_lc = FALSE; /* whether to initialize the lambda
+                                       components, or to check them */
+    gmx_bool start_reached=FALSE; /* whether the start of component names
+                                     has been reached */
+    gmx_bool vector=FALSE; /* whether there are multiple components */
+    int n = 0; /* current component number */
+    const char *val_start=NULL; /* start of the component name, or NULL
+                                   if not in a value */
+    char *strtod_end;
+    gmx_bool OK=TRUE;
+
+    if (end)
+        *end=str;
+
+
+    if (lc_out && lc_out->N == 0)
+    {
+        initialize_lc = TRUE;
+    }
+
+    if (lc_in == NULL)
+        lc_in = lc_out;
+
+    while(1)
+    {
+        if (!start_reached)
+        {
+            if (isalnum(*str))
+            {
+                vector=FALSE;
+                start_reached=TRUE;
+                val_start=str;
+            }
+            else if (*str=='(')
+            {
+                vector=TRUE;
+                start_reached=TRUE;
+            }
+            else if (! isspace(*str))
+            {
+                gmx_fatal(FARGS, "Error in lambda components in %s", fn);
+            }
+        }
+        else
+        {
+            if (val_start)
+            {
+                if (isspace(*str) || *str==')' || *str==',' || *str=='\0')
+                {
+                    /* end of value */
+                    if (lv == NULL)
+                    {
+                        if (initialize_lc)
+                        {
+                            lambda_components_add(lc_out, val_start, 
+                                                  (str-val_start));
+                        }
+                        else
+                        {
+                            if (!lambda_components_check(lc_out, n, val_start, 
+                                                         (str-val_start)))
+                            {
+                                return FALSE;
+                            }
+                        }
+                    }
+                    else
+                    {
+                        /* add a vector component to lv */
+                        lv->val[n] = strtod(val_start, &strtod_end);
+                        if (val_start == strtod_end)
+                        {
+                            gmx_fatal(FARGS,
+                                      "Error reading lambda vector in %s", fn);
+                        }
+                    }
+                    /* reset for the next identifier */
+                    val_start=NULL;
+                    n++;
+                    if (!vector)
+                    {
+                        return OK;
+                    }
+                }
+            }
+            else if (isalnum(*str))
+            {
+                val_start=str;
+            }
+            if (*str == ')')
+            {
+                str++;
+                if (end)
+                    *end=str;
+                if (!vector)
+                {
+                    gmx_fatal(FARGS, "Error in lambda components in %s", fn);
+                }
+                else
+                {
+                    if (n == lc_in->N)
+                    {
+                        return OK;
+                    }
+                    else if (lv == NULL)
+                    {
+                        return FALSE;
+                    }
+                    else
+                    {
+                        gmx_fatal(FARGS, "Incomplete lambda vector data in %s", 
+                                  fn);
+                        return FALSE;
+                    }
+
+                }
+            }
+        }
+        if (*str == '\0')
+        {
+            break;
+        }
+        str++;
+        if (end)
+        {
+            *end=str;
+        }
+    }
+    if (vector)
+    {
+        gmx_fatal(FARGS, "Incomplete lambda components data in %s", fn);
+        return FALSE;
+    }
+    return OK;
+}
+
+/* read and check the component names from a string */
+static gmx_bool read_lambda_components(const char *str,
+                                        lambda_components_t *lc,
+                                        const char **end,
+                                        const char *fn)
+{
+    return read_lambda_compvec(str, NULL, NULL, lc, end, fn);
+}
+
+/* read an initialized lambda vector from a string */
+static gmx_bool read_lambda_vector(const char *str,
+                                   lambda_vec_t *lv,
+                                   const char **end,
+                                   const char *fn)
+{
+    return read_lambda_compvec(str, lv, lv->lc, NULL, end, fn);
+}
+
+
+
 /* deduce lambda value from legend. 
-input:
-    bdhdl = if true, value may be a derivative. 
-output:
-    bdhdl = whether the legend was for a derivative.
+    fn = the file name
+    legend = the legend string
+    ba = the xvg data
+    lam = the initialized lambda vector
+returns whether to use the data in this set.
     */
-static double legend2lambda(char *fn,const char *legend,gmx_bool *bdhdl)
+static gmx_bool legend2lambda(const char *fn,
+                              const char *legend,
+                              xvg_t *ba,
+                              lambda_vec_t *lam)
 {
     double lambda=0;
-    const char   *ptr;
+    const char   *ptr=NULL, *ptr2=NULL;
     gmx_bool ok=FALSE;
+    gmx_bool bdhdl=FALSE;
+    const char *tostr=" to ";
 
     if (legend == NULL)
     {
         gmx_fatal(FARGS,"There is no legend in file '%s', can not deduce lambda",fn);
     }
-    ptr = strrchr(legend,' ');
 
-    if (strstr(legend,"dH"))
+    /* look for the last 'to': */
+    ptr2=legend;
+    do
     {
-        if (! (*bdhdl))
+        ptr2 = strstr(ptr2, tostr);
+        if (ptr2!=NULL)
         {
-            ok=FALSE;
-        }
-        else
-        {
-            ok=TRUE;
+            ptr=ptr2;
+            ptr2++;
         }
     }
+    while(ptr2!=NULL && *ptr2!= '\0' );
+
+    if (ptr)
+    {
+        ptr += strlen(tostr)-1; /* and advance past that 'to' */
+    }
     else
     {
-        if (strchr(legend,'D') != NULL && strchr(legend,'H') != NULL)
+        /* look for the = sign */
+        ptr = strrchr(legend,'=');
+        if (!ptr)
         {
-            ok=TRUE;
-            *bdhdl=FALSE;
+            /* otherwise look for the last space */
+            ptr = strrchr(legend,' ');
         }
     }
+
+    if (strstr(legend,"dH"))
+    {
+        ok=TRUE;
+        bdhdl=TRUE;
+    }
+    else if (strchr(legend,'D') != NULL && strchr(legend,'H') != NULL)
+    {
+        ok=TRUE;
+        bdhdl=FALSE;
+    }
+    else /*if (strstr(legend, "pV"))*/
+    {
+        return FALSE;
+    }
     if (!ptr)
     {
         ok=FALSE;
@@ -1811,52 +2444,194 @@ static double legend2lambda(char *fn,const char *legend,gmx_bool *bdhdl)
 
     if (!ok)
     {
-        printf("%s\n", legend);
         gmx_fatal(FARGS,"There is no proper lambda legend in file '%s', can not deduce lambda",fn);
     }
-    if (sscanf(ptr,"%lf",&lambda) != 1)
+    if (!bdhdl)
     {
-        gmx_fatal(FARGS,"There is no proper lambda legend in file '%s', can not deduce lambda",fn);
+        ptr=find_value(ptr);
+        if (!ptr || !read_lambda_vector(ptr, lam, NULL, fn))
+        {
+            gmx_fatal(FARGS, "lambda vector '%s' %s faulty", legend, fn);
+        }
     }
+    else
+    {
+        int dhdl_index;
+        const char *end;
+        char buf[STRLEN];
 
-    return lambda;
+        ptr = strrchr(legend, '=');
+        end=ptr;
+        if (ptr)
+        {
+            /* there must be a component name */
+            ptr--;
+            if (ptr < legend)
+            {
+                gmx_fatal(FARGS, "dhdl legend '%s' %s faulty", legend, fn);
+            }
+            /* now backtrack to the start of the identifier */
+            while(isspace(*ptr))
+            {
+                end=ptr;
+                ptr--;
+                if (ptr < legend)
+                {
+                    gmx_fatal(FARGS, "dhdl legend '%s' %s faulty", legend, fn);
+                }
+            }
+            while(!isspace(*ptr))
+            {
+                ptr--;
+                if (ptr < legend)
+                {
+                    gmx_fatal(FARGS, "dhdl legend '%s' %s faulty", legend, fn);
+                }
+            }
+            ptr++;
+            strncpy(buf, ptr, (end-ptr));
+            buf[(end-ptr)]='\0';
+            dhdl_index=lambda_components_find(lam->lc, ptr, (end-ptr));
+            if (dhdl_index < 0)
+            {
+                char buf[STRLEN];
+                strncpy(buf, ptr, (end-ptr));
+                buf[(end-ptr)]='\0';
+                gmx_fatal(FARGS,
+                          "Did not find lambda component for '%s' in %s",
+                          buf, fn);
+            }
+        }
+        else
+        {
+            if (lam->lc->N > 1)
+            {
+                gmx_fatal(FARGS,
+                   "dhdl without component name with >1 lambda component in %s",
+                   fn);
+            }
+            dhdl_index=0;
+        }
+        lam->dhdl = dhdl_index;
+    }
+    return TRUE;
 }
 
-static gmx_bool subtitle2lambda(const char *subtitle,double *lambda)
+static gmx_bool subtitle2lambda(const char *subtitle, xvg_t *ba, const char *fn,
+                                lambda_components_t *lc)
 {
     gmx_bool bFound;
-    char *ptr;
+    const char *ptr;
+    char *end;
+    double native_lambda;
 
     bFound = FALSE;
 
-    /* plain text lambda string */
-    ptr = strstr(subtitle,"lambda");
-    if (ptr == NULL)
-    {
-        /* xmgrace formatted lambda string */
-        ptr = strstr(subtitle,"\\xl\\f{}");
-    }
-    if (ptr == NULL)
-    {
-        /* xmgr formatted lambda string */
-        ptr = strstr(subtitle,"\\8l\\4");
-    }
-    if (ptr != NULL)
+    /* first check for a state string */
+    ptr = strstr(subtitle, "state");
+    if (ptr)
     {
-        ptr = strstr(ptr,"=");
+        int index=-1;
+        const char *val_end;
+
+        /* the new 4.6 style lambda vectors */
+        ptr = find_value(ptr);
+        if (ptr)
+        {
+            index = strtol(ptr, &end, 10);
+            if (ptr == end)
+            {
+                gmx_fatal(FARGS,"Incomplete state data in %s", fn);
+                return FALSE;
+            }
+            ptr=end;
+        }
+        else
+        {
+            gmx_fatal(FARGS,"Incomplete state data in %s", fn);
+            return FALSE;
+        }
+        /* now find the lambda vector component names */
+        while(*ptr!='(' && ! isalnum(*ptr))
+        {
+            ptr++;
+            if (*ptr == '\0')
+            {
+                gmx_fatal(FARGS,
+                          "Incomplete lambda vector component data in %s", fn);
+                return FALSE;
+            }
+        }
+        val_end=ptr;
+        if (!read_lambda_components(ptr, lc, &val_end, fn))
+        {
+            gmx_fatal(FARGS,
+                      "lambda vector components in %s don't match those previously read", 
+                      fn);
+        }
+        ptr=find_value(val_end);
+        if (!ptr)
+        {
+            gmx_fatal(FARGS,"Incomplete state data in %s", fn);
+            return FALSE;
+        }
+        lambda_vec_init(&(ba->native_lambda), lc);
+        if (!read_lambda_vector(ptr, &(ba->native_lambda), NULL, fn))
+        {
+            gmx_fatal(FARGS, "lambda vector in %s faulty", fn);
+        }
+        ba->native_lambda.index=index;
+        bFound=TRUE;
     }
-    if (ptr != NULL)
+    else
     {
-        bFound = (sscanf(ptr+1,"%lf",lambda) == 1);
+        /* compatibility mode: check for lambda in other ways. */
+        /* plain text lambda string */
+        ptr = strstr(subtitle,"lambda");
+        if (ptr == NULL)
+        {
+            /* xmgrace formatted lambda string */
+            ptr = strstr(subtitle,"\\xl\\f{}");
+        }
+        if (ptr == NULL)
+        {
+            /* xmgr formatted lambda string */
+            ptr = strstr(subtitle,"\\8l\\4");
+        }
+        if (ptr != NULL)
+        {
+            ptr = strstr(ptr,"=");
+        }
+        if (ptr != NULL)
+        {
+            bFound = (sscanf(ptr+1,"%lf",&(native_lambda)) == 1);
+            /* add the lambda component name as an empty string */
+            if (lc->N > 0)
+            {
+                if (!lambda_components_check(lc, 0, "", 0))
+                {
+                    gmx_fatal(FARGS,
+                              "lambda vector components in %s don't match those previously read", 
+                              fn);
+                }
+            }
+            else
+            {
+                lambda_components_add(lc, "", 0);
+            }
+            lambda_vec_init(&(ba->native_lambda), lc);
+            ba->native_lambda.val[0]=native_lambda;
+        }
     }
 
     return bFound;
 }
 
-static double filename2lambda(char *fn)
+static void filename2lambda(const char *fn, xvg_t *ba)
 {
     double lambda;
-    char   *ptr,*endptr,*digitptr;
+    const char   *ptr,*digitptr;
+    char *endptr;
     int     dirsep;
     ptr = fn;
     /* go to the end of the path string and search backward to find the last 
@@ -1898,16 +2673,17 @@ static double filename2lambda(char *fn)
     {
         gmx_fatal(FARGS,"Malformed number in file path '%s'",fn);
     }
-
-    return lambda;
 }
 
-static void read_bar_xvg_lowlevel(char *fn, real *temp, xvg_t *ba)
+static void read_bar_xvg_lowlevel(const char *fn, real *temp, xvg_t *ba,
+                                  lambda_components_t *lc)
 {
     int  i;
     char *subtitle,**legend,*ptr;
     int np;
     gmx_bool native_lambda_read=FALSE;
+    char buf[STRLEN];
+    lambda_vec_t lv;
 
     xvg_init(ba);
 
@@ -1918,16 +2694,22 @@ static void read_bar_xvg_lowlevel(char *fn, real *temp, xvg_t *ba)
     {
         gmx_fatal(FARGS,"File %s contains no usable data.",fn);
     }
+    /* Reorder the data */
     ba->t  = ba->y[0];
+    for(i=1; i<ba->nset; i++)
+    {
+        ba->y[i-1] = ba->y[i];
+    }
+    ba->nset--;
 
     snew(ba->np,ba->nset);
     for(i=0;i<ba->nset;i++)
         ba->np[i]=np;
 
-
     ba->temp = -1;
     if (subtitle != NULL)
     {
+        /* try to extract temperature */
         ptr = strstr(subtitle,"T =");
         if (ptr != NULL)
         {
@@ -1954,21 +2736,21 @@ static void read_bar_xvg_lowlevel(char *fn, real *temp, xvg_t *ba)
     /* Try to deduce lambda from the subtitle */
     if (subtitle)
     {
-        if (subtitle2lambda(subtitle,&(ba->native_lambda)))
+        if (subtitle2lambda(subtitle,ba, fn, lc))
         {
             native_lambda_read=TRUE;
         }
     }
-    snew(ba->lambda,ba->nset-1);
+    snew(ba->lambda,ba->nset);
     if (legend == NULL)
     {
-        /* Check if we have a single set, no legend, nset=2 means t and dH/dl */
-        if (ba->nset == 2)
+        /* Check if we have a single set, no legend, nset=1 means t and dH/dl */
+        if (ba->nset == 1)
         {
             if (!native_lambda_read)
             {
                 /* Deduce lambda from the file name */
-                ba->native_lambda = filename2lambda(fn);
+                filename2lambda(fn, ba);
                 native_lambda_read=TRUE;
             }
             ba->lambda[0] = ba->native_lambda;
@@ -1980,16 +2762,28 @@ static void read_bar_xvg_lowlevel(char *fn, real *temp, xvg_t *ba)
     }
     else
     {
-        for(i=0; i<ba->nset-1; i++)
+        for(i=0; i<ba->nset)
         {
-            gmx_bool is_dhdl=(i==0);
+            gmx_bool use=FALSE;
             /* Read lambda from the legend */
-            ba->lambda[i] = legend2lambda(fn,legend[i], &is_dhdl);
-
-            if (is_dhdl && !native_lambda_read)
+            lambda_vec_init( &(ba->lambda[i]), lc );
+            lambda_vec_copy( &(ba->lambda[i]), &(ba->native_lambda));
+            use=legend2lambda(fn,legend[i], ba, &(ba->lambda[i]));
+            if (use)
             {
-                ba->native_lambda = ba->lambda[i];
-                native_lambda_read=TRUE;
+                lambda_vec_print(&(ba->lambda[i]), buf, FALSE);
+                i++;
+            }
+            else
+            {
+                int j;
+                printf("%s: Ignoring set '%s'.\n", fn, legend[i]);
+                for(j=i+1; j<ba->nset; j++)
+                {
+                    ba->y[j-1] = ba->y[j];
+                    legend[j-1] = legend[j];
+                }
+                ba->nset--;
             }
         }
     }
@@ -1999,11 +2793,6 @@ static void read_bar_xvg_lowlevel(char *fn, real *temp, xvg_t *ba)
         gmx_fatal(FARGS,"File %s contains multiple sets but no indication of the native lambda",fn);
     }
     
-    /* Reorder the data */
-    for(i=1; i<ba->nset; i++)
-    {
-        ba->y[i-1] = ba->y[i];
-    }
     if (legend != NULL)
     {
         for(i=0; i<ba->nset-1; i++)
@@ -2012,10 +2801,9 @@ static void read_bar_xvg_lowlevel(char *fn, real *temp, xvg_t *ba)
         }
         sfree(legend);
     }
-    ba->nset--;
 }
 
-static void read_bar_xvg(char *fn, real *temp, lambda_t *lambda_head)
+static void read_bar_xvg(char *fn, real *temp, sim_data_t *sd)
 {
     xvg_t *barsim;
     samples_t *s;
@@ -2024,7 +2812,7 @@ static void read_bar_xvg(char *fn, real *temp, lambda_t *lambda_head)
 
     snew(barsim,1);
 
-    read_bar_xvg_lowlevel(fn, temp, barsim);
+    read_bar_xvg_lowlevel(fn, temp, barsim, &(sd->lc));
 
     if (barsim->nset <1 )
     {
@@ -2041,34 +2829,41 @@ static void read_bar_xvg(char *fn, real *temp, lambda_t *lambda_head)
     snew(s, barsim->nset);
     for(i=0;i<barsim->nset;i++)
     {
-        samples_init(s+i, barsim->native_lambda, barsim->lambda[i], 
-                     barsim->temp, lambda_same(barsim->native_lambda,
-                                               barsim->lambda[i]), 
+        samples_init(s+i, &(barsim->native_lambda), &(barsim->lambda[i]),
+                     barsim->temp, lambda_vec_same(&(barsim->native_lambda),
+                                                   &(barsim->lambda[i])),
                      fn);
         s[i].du=barsim->y[i];
         s[i].ndu=barsim->np[i];
         s[i].t=barsim->t;
 
-        lambda_list_insert_sample(lambda_head, s+i);
+        lambda_data_list_insert_sample(sd->lb, s+i);
     }
-    printf("%s: %.1f - %.1f; lambda = %.3f\n    foreign lambdas:", 
-           fn, s[0].t[0], s[0].t[s[0].ndu-1], s[0].native_lambda);
-    for(i=0;i<barsim->nset;i++)
     {
-        printf(" %.3f (%d pts)", s[i].foreign_lambda, s[i].ndu);
+        char buf[STRLEN];
+
+        lambda_vec_print(s[0].native_lambda, buf, FALSE);
+        printf("%s: %.1f - %.1f; lambda = %s\n    dH/dl & foreign lambdas:\n", 
+               fn, s[0].t[0], s[0].t[s[0].ndu-1], buf);
+        for(i=0;i<barsim->nset;i++)
+        {
+            lambda_vec_print(s[i].foreign_lambda, buf, TRUE);
+            printf("        %s (%d pts)\n", buf, s[i].ndu);
+        }
     }
     printf("\n\n");
 }
 
 static void read_edr_rawdh_block(samples_t **smp, int *ndu, t_enxblock *blk, 
                                  double start_time, double delta_time,
-                                 double native_lambda, double temp,
+                                 lambda_vec_t *native_lambda, double temp,
                                  double *last_t, const char *filename)
 {
-    int j;
+    int i,j;
     gmx_bool allocated;
-    double foreign_lambda;
-    int derivative;
+    double old_foreign_lambda;
+    lambda_vec_t *foreign_lambda;
+    int type;
     samples_t *s; /* convenience pointer */
     int startj;
 
@@ -2087,16 +2882,34 @@ static void read_edr_rawdh_block(samples_t **smp, int *ndu, t_enxblock *blk,
                   "Unexpected/corrupted block data in file %s around time %g.", 
                   filename, start_time);
     }
-   
-    derivative = blk->sub[0].ival[0]; 
-    foreign_lambda = blk->sub[1].dval[0];
+
+    snew(foreign_lambda, 1);
+    lambda_vec_init(foreign_lambda, native_lambda->lc);
+    lambda_vec_copy(foreign_lambda, native_lambda);
+    type = blk->sub[0].ival[0];
+    if (type == dhbtDH)
+    {
+        for(i=0;i<native_lambda->lc->N;i++)
+        {
+            foreign_lambda->val[i] = blk->sub[1].dval[i];
+        }
+    }
+    else
+    {
+        if (blk->sub[0].nr > 1)
+        {
+            foreign_lambda->dhdl = blk->sub[0].ival[1];
+        }
+        else
+            foreign_lambda->dhdl = 0;
+    }
 
     if (! *smp)
     {
         /* initialize the samples structure if it's empty. */
         snew(*smp, 1);
         samples_init(*smp, native_lambda, foreign_lambda, temp,
-                     derivative!=0, filename);
+                     type==dhbtDHDL, filename);
         (*smp)->start_time=start_time;
         (*smp)->delta_time=delta_time;
     }
@@ -2105,13 +2918,12 @@ static void read_edr_rawdh_block(samples_t **smp, int *ndu, t_enxblock *blk,
     s=*smp;
 
     /* now double check */
-    if ( ! lambda_same(s->foreign_lambda, foreign_lambda) ||
-         (  (derivative!=0) != (s->derivative!=0) ) )
+    if ( ! lambda_vec_same(s->foreign_lambda, foreign_lambda) )
     {
-        fprintf(stderr, "Got foreign lambda=%g, expected: %g\n", 
-                foreign_lambda, s->foreign_lambda);
-        fprintf(stderr, "Got derivative=%d, expected: %d\n", 
-                derivative, s->derivative);
+        char buf[STRLEN], buf2[STRLEN];
+        lambda_vec_print(foreign_lambda, buf, FALSE);
+        lambda_vec_print(s->foreign_lambda, buf2, FALSE);
+        fprintf(stderr, "Got foreign lambda=%s, expected: %s\n", buf, buf2);
         gmx_fatal(FARGS, "Corrupted data in file %s around t=%g.", 
                   filename, start_time);
     }
@@ -2149,14 +2961,15 @@ static void read_edr_rawdh_block(samples_t **smp, int *ndu, t_enxblock *blk,
 
 static samples_t *read_edr_hist_block(int *nsamples, t_enxblock *blk,
                                       double start_time, double delta_time,
-                                      double native_lambda, double temp,
+                                      lambda_vec_t *native_lambda, double temp,
                                       double *last_t, const char *filename)
 {
     int i,j;
     samples_t *s;
     int nhist;
-    double foreign_lambda;
-    int derivative;
+    double old_foreign_lambda;
+    lambda_vec_t *foreign_lambda;
+    int type;
     int nbins[2];
 
     /* check the block types etc. */
@@ -2186,13 +2999,53 @@ static samples_t *read_edr_hist_block(int *nsamples, t_enxblock *blk,
     snew(s, 1);
     *nsamples=1;
 
-    foreign_lambda=blk->sub[0].dval[0];
-    derivative=(int)(blk->sub[1].lval[1]);
-    if (derivative)
-        foreign_lambda=native_lambda;
+    snew(foreign_lambda, 1);
+    lambda_vec_init(foreign_lambda, native_lambda->lc);
+    lambda_vec_copy(foreign_lambda, native_lambda);
+    type = (int)(blk->sub[1].lval[1]);
+    if (type == dhbtDH)
+    {
+        double old_foreign_lambda;
+
+        old_foreign_lambda=blk->sub[0].dval[0];
+        if (old_foreign_lambda >= 0)
+        {
+            foreign_lambda->val[0]=old_foreign_lambda;
+            if (foreign_lambda->lc->N > 1)
+            {
+                gmx_fatal(FARGS,
+                          "Single-component lambda in multi-component file %s", 
+                          filename);
+            }
+        }
+        else
+        {
+            for(i=0;i<native_lambda->lc->N;i++)
+            {
+                foreign_lambda->val[i] = blk->sub[0].dval[i+2];
+            }
+        }
+    }
+    else
+    {
+        if (foreign_lambda->lc->N > 1)
+        {
+            if (blk->sub[1].nr < 3 + nhist)
+            {
+                gmx_fatal(FARGS,
+                        "Missing derivative coord in multi-component file %s", 
+                        filename);
+            }
+            foreign_lambda->dhdl = blk->sub[1].lval[2 + nhist];
+        }
+        else
+        {
+            foreign_lambda->dhdl = 0;
+        }
+    }
 
-    samples_init(s, native_lambda, foreign_lambda, temp,
-                 derivative!=0, filename);
+    samples_init(s, native_lambda, foreign_lambda, temp, type==dhbtDHDL,
+                 filename);
     snew(s->hist, 1);
 
     for(i=0;i<nhist;i++)
@@ -2204,10 +3057,12 @@ static samples_t *read_edr_hist_block(int *nsamples, t_enxblock *blk,
 
     for(i=0;i<nhist;i++)
     {
-        s->hist->x0[i]=blk->sub[1].lval[2+i];
+        s->hist->x0[i] = blk->sub[1].lval[2+i];
         s->hist->dx[i] = blk->sub[0].dval[1];
         if (i==1)
+        {
             s->hist->dx[i] = - s->hist->dx[i];
+        }
     }
 
     s->hist->start_time = start_time;
@@ -2251,9 +3106,9 @@ static samples_t *read_edr_hist_block(int *nsamples, t_enxblock *blk,
 }
 
 
-static void read_barsim_edr(char *fn, real *temp, lambda_t *lambda_head)
+static void read_barsim_edr(char *fn, real *temp, sim_data_t *sd)
 {
-    int i;
+    int i,j;
     ener_file_t fp;
     t_enxframe *fr; 
     int nre;
@@ -2263,15 +3118,19 @@ static void read_barsim_edr(char *fn, real *temp, lambda_t *lambda_head)
     samples_t **samples_rawdh=NULL; /* contains samples for raw delta_h  */
     int *nhists=NULL;       /* array to keep count & print at end */
     int *npts=NULL;         /* array to keep count & print at end */
-    double *lambdas=NULL;   /* array to keep count & print at end */
-    double native_lambda=-1;
+    lambda_vec_t **lambdas=NULL;   /* array to keep count & print at end */
+    lambda_vec_t *native_lambda;
     double end_time;        /* the end time of the last batch of samples */
     int nsamples=0;
+    lambda_vec_t start_lambda;
 
     fp = open_enx(fn,"r");
     do_enxnms(fp,&nre,&enm);
     snew(fr, 1);
 
+    snew(native_lambda, 1);
+    start_lambda.lc = NULL;
+
     while(do_enx(fp, fr))
     {
         /* count the data blocks */
@@ -2280,7 +3139,7 @@ static void read_barsim_edr(char *fn, real *temp, lambda_t *lambda_head)
         int nlam=0;
         int k;
         /* DHCOLL block information: */
-        double start_time=0, delta_time=0, start_lambda=0, delta_lambda=0;
+        double start_time=0, delta_time=0, old_start_lambda=0, delta_lambda=0;
         double rtemp=0;
 
         /* count the blocks and handle collection information: */
@@ -2304,7 +3163,7 @@ static void read_barsim_edr(char *fn, real *temp, lambda_t *lambda_head)
                 rtemp =        fr->block[i].sub[0].dval[0];
                 start_time =   fr->block[i].sub[0].dval[1];
                 delta_time =   fr->block[i].sub[0].dval[2];
-                start_lambda = fr->block[i].sub[0].dval[3];
+                old_start_lambda = fr->block[i].sub[0].dval[3];
                 delta_lambda = fr->block[i].sub[0].dval[4];
 
                 if (delta_lambda>0)
@@ -2317,6 +3176,62 @@ static void read_barsim_edr(char *fn, real *temp, lambda_t *lambda_head)
                 }
                 *temp=rtemp;
 
+                if (old_start_lambda >= 0)
+                {
+                    if (sd->lc.N > 0)
+                    {
+                        if (!lambda_components_check(&(sd->lc), 0, "", 0))
+                        {
+                            gmx_fatal(FARGS,
+                                      "lambda vector components in %s don't match those previously read",
+                                      fn);
+                        }
+                    }
+                    else
+                    {
+                        lambda_components_add(&(sd->lc), "", 0);
+                    }
+                    if (!start_lambda.lc)
+                    {
+                        lambda_vec_init(&start_lambda, &(sd->lc));
+                    }
+                    start_lambda.val[0]=old_start_lambda;
+                }
+                else
+                {
+                    /* read lambda vector */
+                    int n_lambda_vec;
+                    gmx_bool check=(sd->lc.N > 0);
+                    if (fr->block[i].nsub < 2)
+                    {
+                        gmx_fatal(FARGS, 
+                                  "No lambda vector, but start_lambda=%g\n",
+                                  old_start_lambda);
+                    }
+                    n_lambda_vec=fr->block[i].sub[1].ival[1];
+                    for(j=0;j<n_lambda_vec;j++)
+                    {
+                        const char *name=
+                             efpt_singular_names[fr->block[i].sub[1].ival[1+j]];
+                        if (check)
+                        {
+                            /* check the components */
+                            lambda_components_check(&(sd->lc), j, name,
+                                                    strlen(name));
+                        }
+                        else
+                        {
+                            lambda_components_add(&(sd->lc), name, 
+                                                  strlen(name));
+                        }
+                    }
+                    lambda_vec_init(&start_lambda, &(sd->lc));
+                    start_lambda.index=fr->block[i].sub[1].ival[0];
+                    for(j=0;j<n_lambda_vec;j++)
+                    {
+                        start_lambda.val[j]=fr->block[i].sub[0].dval[5+j];
+                    }
+                }
                 if (first_t < 0)
                     first_t=start_time;
             }
@@ -2324,7 +3239,7 @@ static void read_barsim_edr(char *fn, real *temp, lambda_t *lambda_head)
 
         if (nlam != 1)
         {
-            gmx_fatal(FARGS, "Did not find a delta h information in file %s" , fn);
+            gmx_fatal(FARGS, "Did not find delta H information in file %s", fn);
         }
         if (nblocks_raw > 0 && nblocks_hist > 0 )
         {
@@ -2334,7 +3249,7 @@ static void read_barsim_edr(char *fn, real *temp, lambda_t *lambda_head)
         if (nsamples > 0)
         {
             /* check the native lambda */
-            if (!lambda_same(start_lambda, native_lambda) )
+            if (!lambda_vec_same(&start_lambda, native_lambda) )
             {
                 gmx_fatal(FARGS, "Native lambda not constant in file %s: started at %g, and becomes %g at time %g", 
                           fn, native_lambda, start_lambda, start_time);
@@ -2355,8 +3270,8 @@ static void read_barsim_edr(char *fn, real *temp, lambda_t *lambda_head)
                     if (samples_rawdh[i])
                     {
                         /* insert it into the existing list */
-                        lambda_list_insert_sample(lambda_head, 
-                                                  samples_rawdh[i]);
+                        lambda_data_list_insert_sample(sd->lb,
+                                                       samples_rawdh[i]);
                         /* and make sure we'll allocate a new one this time
                            around */
                         samples_rawdh[i]=NULL;
@@ -2368,7 +3283,9 @@ static void read_barsim_edr(char *fn, real *temp, lambda_t *lambda_head)
         {
             /* this is the first round; allocate the associated data 
                structures */
-            native_lambda=start_lambda;
+            /*native_lambda=start_lambda;*/
+            lambda_vec_init(native_lambda, &(sd->lc));
+            lambda_vec_copy(native_lambda, &start_lambda);
             nsamples=nblocks_raw+nblocks_hist;
             snew(nhists, nsamples);
             snew(npts, nsamples);
@@ -2378,7 +3295,7 @@ static void read_barsim_edr(char *fn, real *temp, lambda_t *lambda_head)
             {
                 nhists[i]=0;
                 npts[i]=0;
-                lambdas[i]=-1;
+                lambdas[i]=NULL;
                 samples_rawdh[i]=NULL; /* init to NULL so we know which
                                           ones contain values */
             }
@@ -2388,41 +3305,49 @@ static void read_barsim_edr(char *fn, real *temp, lambda_t *lambda_head)
         k=0; /* counter for the lambdas, etc. arrays */
         for(i=0;i<fr->nblock;i++)
         {
-            if (fr->block[i].id == enxDH)
-            {
-                int ndu;
-                read_edr_rawdh_block(&(samples_rawdh[k]),
-                                     &ndu,
-                                     &(fr->block[i]), 
-                                     start_time, delta_time, 
-                                     start_lambda, rtemp, 
-                                     &last_t, fn);
-                npts[k] += ndu;
-                if (samples_rawdh[k])
+            if (fr->block[i].id == enxDH) 
+            {
+                int type=(fr->block[i].sub[0].ival[0]);
+                if (type == dhbtDH || type == dhbtDHDL)
                 {
-                    lambdas[k]=samples_rawdh[k]->foreign_lambda;
+                    int ndu;
+                    read_edr_rawdh_block(&(samples_rawdh[k]),
+                                         &ndu,
+                                         &(fr->block[i]),
+                                         start_time, delta_time,
+                                         native_lambda, rtemp,
+                                         &last_t, fn);
+                    npts[k] += ndu;
+                    if (samples_rawdh[k])
+                    {
+                        lambdas[k]=samples_rawdh[k]->foreign_lambda;
+                    }
+                    k++;
                 }
-                k++;
             }
             else if (fr->block[i].id == enxDHHIST)
             {
-                int j;
-                int nb=0;
-                samples_t *s; /* this is where the data will go */
-                s=read_edr_hist_block(&nb, &(fr->block[i]), 
-                                      start_time, delta_time, 
-                                      start_lambda, rtemp, 
-                                      &last_t, fn);
-                nhists[k] += nb;
-                if (nb>0)
+                int type=(int)(fr->block[i].sub[1].lval[1]);
+                if (type == dhbtDH || type == dhbtDHDL)
                 {
-                    lambdas[k]= s->foreign_lambda;
-                }
-                k++;
-                /* and insert the new sample immediately */
-                for(j=0;j<nb;j++)
-                {
-                    lambda_list_insert_sample(lambda_head, s+j);
+                    int j;
+                    int nb=0;
+                    samples_t *s; /* this is where the data will go */
+                    s=read_edr_hist_block(&nb, &(fr->block[i]),
+                                          start_time, delta_time,
+                                          native_lambda, rtemp,
+                                          &last_t, fn);
+                    nhists[k] += nb;
+                    if (nb>0)
+                    {
+                        lambdas[k]=s->foreign_lambda;
+                    }
+                    k++;
+                    /* and insert the new sample immediately */
+                    for(j=0;j<nb;j++)
+                    {
+                        lambda_data_list_insert_sample(sd->lb, s+j);
+                    }
                 }
             }
         }
@@ -2433,23 +3358,31 @@ static void read_barsim_edr(char *fn, real *temp, lambda_t *lambda_head)
         if (samples_rawdh[i])
         {
             /* insert it into the existing list */
-            lambda_list_insert_sample(lambda_head, samples_rawdh[i]);
+            lambda_data_list_insert_sample(sd->lb, samples_rawdh[i]);
         }
     }
 
 
-    fprintf(stderr, "\n");
-    printf("%s: %.1f - %.1f; lambda = %.3f\n    foreign lambdas:", 
-           fn, first_t, last_t, native_lambda);
-    for(i=0;i<nsamples;i++)
     {
-        if (nhists[i] > 0)
-        {
-            printf(" %.3f (%d hists)", lambdas[i], nhists[i]);
-        }
-        else
+        char buf[STRLEN];
+        printf("\n");
+        lambda_vec_print(native_lambda, buf, FALSE);
+        printf("%s: %.1f - %.1f; lambda = %s\n    foreign lambdas:\n",
+               fn, first_t, last_t, buf);
+        for(i=0;i<nsamples;i++)
         {
-            printf(" %.3f (%d pts)", lambdas[i], npts[i]);
+            if (lambdas[i])
+            {
+                lambda_vec_print(lambdas[i], buf, TRUE);
+                if (nhists[i] > 0)
+                {
+                    printf("        %s (%d hists)\n", buf, nhists[i]);
+                }
+                else
+                {
+                    printf("        %s (%d pts)\n", buf, npts[i]);
+                }
+            }
         }
     }
     printf("\n\n");
@@ -2595,16 +3528,15 @@ int gmx_bar(int argc,char *argv[])
     int      nedrfile=0;
     char     **fxvgnms;
     char     **fedrnms;
-    lambda_t *lb;    /* the pre-processed lambda data (linked list head) */
-    lambda_t lambda_head; /* the head element */
+    sim_data_t sim_data; /* the simulation data */
     barres_t *results;  /* the results */
     int    nresults;  /* number of results in results array */
 
     double   *partsum;
     double   prec,dg_tot,dg,sig, dg_tot_max, dg_tot_min;
     FILE     *fpb,*fpi;
-    char     lamformat[20];
-    char     dgformat[20],xvg2format[STRLEN],xvg3format[STRLEN],buf[STRLEN];
+    char     dgformat[20],xvg2format[STRLEN],xvg3format[STRLEN];
+    char     buf[STRLEN], buf2[STRLEN];
     char     ktformat[STRLEN], sktformat[STRLEN];
     char     kteformat[STRLEN], skteformat[STRLEN];
     output_env_t oenv;
@@ -2630,11 +3562,14 @@ int gmx_bar(int argc,char *argv[])
         nedrfile = opt2fns(&fedrnms,"-g",NFILE,fnm);
     }
 
+    sim_data_init(&sim_data);
+#if 0
     /* make linked list */
     lb=&lambda_head;
-    lambda_init(lb, 0, 0);
+    lambda_data_init(lb, 0, 0);
     lb->next=lb;
     lb->prev=lb;
+#endif
 
 
     nfile_tot = nxvgfile + nedrfile;
@@ -2656,26 +3591,26 @@ int gmx_bar(int argc,char *argv[])
     /* read in all files. First xvg files */
     for(f=0; f<nxvgfile; f++)
     {
-        read_bar_xvg(fxvgnms[f],&temp,lb);
+        read_bar_xvg(fxvgnms[f],&temp,&sim_data);
         nf++;
     }
     /* then .edr files */
     for(f=0; f<nedrfile; f++)
     {
-        read_barsim_edr(fedrnms[f],&temp,lb);;
+        read_barsim_edr(fedrnms[f],&temp,&sim_data);;
         nf++;
     }
 
     /* fix the times to allow for equilibration */
-    lambdas_impose_times(lb, begin, end);
+    sim_data_impose_times(&sim_data, begin, end);
 
     if (opt2bSet("-oh",NFILE,fnm))
     {
-        lambdas_histogram(lb, opt2fn("-oh",NFILE,fnm), nbin, oenv);
+        sim_data_histogram(&sim_data, opt2fn("-oh",NFILE,fnm), nbin, oenv);
     }
    
     /* assemble the output structures from the lambdas */
-    results=barres_list_create(lb, &nresults, use_dhdl);
+    results=barres_list_create(&sim_data, &nresults, use_dhdl);
 
     sum_disc_err=barres_list_max_disc_err(results, nresults);
 
@@ -2693,7 +3628,7 @@ int gmx_bar(int argc,char *argv[])
     }
 
 
-    sprintf(lamformat,"%%6.3f");
+    /*sprintf(lamformat,"%%6.3f");*/
     sprintf( dgformat,"%%%d.%df",3+nd,nd);
     /* the format strings of the results in kT */
     sprintf( ktformat,"%%%d.%df",5+nd,nd);
@@ -2701,8 +3636,8 @@ int gmx_bar(int argc,char *argv[])
     /* the format strings of the errors in kT */
     sprintf( kteformat,"%%%d.%df",3+nd,nd);
     sprintf( skteformat,"%%%ds",4+nd);
-    sprintf(xvg2format,"%s %s\n","%g",dgformat);
-    sprintf(xvg3format,"%s %s %s\n","%g",dgformat,dgformat);
+    sprintf(xvg2format,"%s %s\n","%s",dgformat);
+    sprintf(xvg3format,"%s %s %s\n","%s",dgformat,dgformat);
 
 
 
@@ -2772,10 +3707,10 @@ int gmx_bar(int argc,char *argv[])
     printf("\n");
     for(f=0; f<nresults; f++)
     {
-        printf(lamformat, results[f].a->native_lambda);
-        printf(" ");
-        printf(lamformat, results[f].b->native_lambda);
-        printf(" ");
+        lambda_vec_print_short(results[f].a->native_lambda, buf);
+        printf("%s ", buf);
+        lambda_vec_print_short(results[f].b->native_lambda, buf);
+        printf("%s ", buf);
         printf(ktformat,  results[f].dg);
         printf(" ");
         if (bEE)
@@ -2841,24 +3776,24 @@ int gmx_bar(int argc,char *argv[])
         
         if (fpi != NULL)
         {
-            fprintf(fpi, xvg2format, results[f].a->native_lambda, dg_tot);
+            lambda_vec_print_short(results[f].a->native_lambda, buf);
+            fprintf(fpi, xvg2format, buf, dg_tot);
         }
 
 
         if (fpb != NULL)
         {
-            fprintf(fpb, xvg3format,
-                    0.5*(results[f].a->native_lambda + 
-                         results[f].b->native_lambda),
-                    results[f].dg,results[f].dg_err);
+            lambda_vec_print_intermediate(results[f].a->native_lambda,
+                                          results[f].b->native_lambda,
+                                          buf);
+
+            fprintf(fpb, xvg3format, buf, results[f].dg,results[f].dg_err);
         }
 
-        /*printf("lambda %4.2f - %4.2f, DG ", results[f].lambda_a,
-                                              results[f].lambda_b);*/
-        printf("lambda ");
-        printf(lamformat, results[f].a->native_lambda);
-        printf(" - ");
-        printf(lamformat, results[f].b->native_lambda);
+        printf("point ");
+        lambda_vec_print_short(results[f].a->native_lambda, buf);
+        lambda_vec_print_short(results[f].b->native_lambda, buf2);
+        printf("%s - %s", buf, buf2);
         printf(",   DG ");
 
         printf(dgformat,results[f].dg*kT);
@@ -2879,10 +3814,10 @@ int gmx_bar(int argc,char *argv[])
         dg_tot += results[f].dg;
     }
     printf("\n");
-    printf("total  ");
-    printf(lamformat, results[0].a->native_lambda);
-    printf(" - ");
-    printf(lamformat, results[nresults-1].b->native_lambda);
+    printf("total ");
+    lambda_vec_print_short(results[0].a->native_lambda, buf);
+    lambda_vec_print_short(results[nresults-1].b->native_lambda, buf2);
+    printf("%s - %s", buf, buf2);
     printf(",   DG ");
 
     printf(dgformat,dg_tot*kT);
@@ -2917,8 +3852,8 @@ int gmx_bar(int argc,char *argv[])
 
     if (fpi != NULL)
     {
-        fprintf(fpi, xvg2format,
-                results[nresults-1].b->native_lambda, dg_tot);
+        lambda_vec_print_short(results[nresults-1].b->native_lambda, buf);
+        fprintf(fpi, xvg2format, buf, dg_tot);
         ffclose(fpi);
     }
 
index 1851f744369004ec657919146d77f21b9b6716d2..c1fe188fc32e0be5153c6cf43bc6f841d571823a 100644 (file)
@@ -682,7 +682,7 @@ int gmx_disre(int argc,char *argv[])
     isize=0;
 
   ir.dr_tau=0.0;
-  init_disres(fplog,&mtop,&ir,NULL,FALSE,&fcd,NULL);
+  init_disres(fplog,&mtop,&ir,NULL,FALSE,&fcd,NULL,FALSE);
 
   natoms=read_first_x(oenv,&status,ftp2fn(efTRX,NFILE,fnm),&t,&x,box);
   snew(f,5*natoms);
index 72adadac78779db95672961005a439cd869e0250..ee92a3a395a15308ec760257009319bf68c9d4f9 100644 (file)
@@ -1366,8 +1366,10 @@ static void fec(const char *ene2fn, const char *runavgfn,
 }
 
 
-static void do_dhdl(t_enxframe *fr, t_inputrec *ir, FILE **fp_dhdl, const char *filename, gmx_bool bDp,
-                    int *blocks, int *hists, int *samples, int *nlambdas, const output_env_t oenv)
+static void do_dhdl(t_enxframe *fr, t_inputrec *ir, FILE **fp_dhdl,
+                    const char *filename, gmx_bool bDp,
+                    int *blocks, int *hists, int *samples, int *nlambdas,
+                    const output_env_t oenv)
 {
     const char *dhdl="dH/d\\lambda",*deltag="\\DeltaH",*lambda="\\lambda";
     char title[STRLEN],label_x[STRLEN],label_y[STRLEN], legend[STRLEN];
@@ -1378,7 +1380,11 @@ static void do_dhdl(t_enxframe *fr, t_inputrec *ir, FILE **fp_dhdl, const char *
     /* coll data */
     double temp=0, start_time=0, delta_time=0, start_lambda=0, delta_lambda=0;
     static int setnr=0;
+    double *native_lambda_vec=NULL;
+    const char **lambda_components=NULL;
+    int n_lambda_vec=0;
     gmx_bool changing_lambda=FALSE;
+    int lambda_fep_state;
 
     /* now count the blocks & handle the global dh data */
     for(i=0;i<fr->nblock;i++)
@@ -1408,6 +1414,32 @@ static void do_dhdl(t_enxframe *fr, t_inputrec *ir, FILE **fp_dhdl, const char *
             start_lambda = fr->block[i].sub[0].dval[3];
             delta_lambda = fr->block[i].sub[0].dval[4];
             changing_lambda = (delta_lambda != 0);
+            if (fr->block[i].nsub > 1)
+            {
+                lambda_fep_state=fr->block[i].sub[1].ival[0];
+                if (n_lambda_vec==0)
+                {
+                    n_lambda_vec=fr->block[i].sub[1].ival[1];
+                }
+                else
+                {
+                    if (n_lambda_vec!=fr->block[i].sub[1].ival[1])
+                    {
+                        gmx_fatal(FARGS,
+                                  "Unexpected change of basis set in lambda");
+                    }
+                }
+                if (lambda_components == NULL)
+                    snew(lambda_components, n_lambda_vec);
+                if (native_lambda_vec == NULL)
+                    snew(native_lambda_vec, n_lambda_vec);
+                for(j=0;j<n_lambda_vec;j++)
+                {
+                    native_lambda_vec[j] = fr->block[i].sub[0].dval[5+j];
+                    lambda_components[j] =
+                           efpt_singular_names[fr->block[i].sub[1].ival[2+j]];
+                }
+            }
         }
     }
 
@@ -1424,7 +1456,12 @@ static void do_dhdl(t_enxframe *fr, t_inputrec *ir, FILE **fp_dhdl, const char *
     {
         if (nblock_dh>0)
         {
-            /* we have standard, non-histogram data -- call open_dhdl to open the file */
+            /* we have standard, non-histogram data --
+               call open_dhdl to open the file */
+            /* TODO this is an ugly hack that needs to be fixed: this will only
+               work if the order of data is always the same and if we're
+               only using the g_energy compiled with the mdrun that produced
+               the ener.edr. */
             *fp_dhdl=open_dhdl(filename,ir,oenv);
         }
         else
index 5e42c438ec891ee8b1086d953c177db2e79da014..de5095eb76253f066e55dc5fa7e7b554bf98c0bf 100644 (file)
@@ -117,11 +117,6 @@ int gmx_membed(int argc,char *argv[])
     gmx_bool bVerbose=FALSE;
     char *mdrun_path=NULL;
 
-/* arguments relevant to OPENMM only*/
-#ifdef GMX_OPENMM
-    gmx_fatal(FARGS,"g_membed not implemented for openmm");
-#endif
-
     t_pargs pa[] = {
         { "-xyinit",   FALSE, etREAL,  {&xy_fac},
             "Resize factor for the protein in the xy dimension before starting embedding" },
index 0dc1775bfb5f0cb1e8651d7dc831fcb2918c2b8d..3f0a2fe6823be795123e740d9278263f89098d5e 100644 (file)
@@ -918,7 +918,9 @@ int gmx_trjconv(int argc,char *argv[])
 
         bSubTraj = opt2bSet("-sub",NFILE,fnm);
         if (bSubTraj) {
-            if ((ftp != efXTC) && (ftp != efTRN))
+            if ((ftp != efXTC) && (ftp != efTRR))
+                /* It seems likely that other trajectory file types
+                 * could work here. */
                 gmx_fatal(FARGS,"Can only use the sub option with output file types "
                           "xtc and trr");
             clust = cluster_index(NULL,opt2fn("-sub",NFILE,fnm));
@@ -1538,7 +1540,7 @@ int gmx_trjconv(int argc,char *argv[])
             ffclose(out);
         if (bSubTraj) {
             for(i=0; (i<clust->clust->nr); i++)
-                if (clust_status[i] )
+                if (clust_status_id[i] >= 0 )
                     close_trx(clust_status[i]);
         }
     }
index 2397b3beaf1bc44accd545030a0321b48b3c820c..11078d6a2f8d046bcf871253ea3f67953d879edb 100644 (file)
@@ -151,9 +151,13 @@ static gmx_bool is_equal(real a, real b)
     if (diff < 0.0) diff = -diff;
 
     if (diff < eps)
+    {
         return TRUE;
+    }
     else
+    {
         return FALSE;
+    }
 }
 
 
@@ -211,7 +215,9 @@ static int parse_logfile(const char *logfile, const char *errfile,
 
     iFound = eFoundNothing;
     if (1 == nnodes)
+    {
         iFound = eFoundDDStr; /* Skip some case statements */
+    }
 
     while (fgets(line, STRLEN, fp) != NULL)
     {
@@ -259,9 +265,13 @@ static int parse_logfile(const char *logfile, const char *errfile,
                     sscanf(line, "Domain decomposition grid %d x %d x %d, separate PME nodes %d",
                             &(perfdata->nx), &(perfdata->ny), &(perfdata->nz), &npme);
                     if (perfdata->nPMEnodes == -1)
+                    {
                         perfdata->guessPME = npme;
+                    }
                     else if (perfdata->nPMEnodes != npme)
+                    {
                         gmx_fatal(FARGS, "PME nodes from command line and output file are not identical");
+                    }
                     iFound = eFoundDDStr;
                 }
                 /* Catch a few errors that might have occured: */
@@ -284,10 +294,14 @@ static int parse_logfile(const char *logfile, const char *errfile,
             case eFoundDDStr:
                 /* Look for PME mesh/force balance (not necessarily present, though) */
                 if (str_starts(line, matchstrbal))
+                {
                     sscanf(&line[strlen(matchstrbal)], "%f", &(perfdata->PME_f_load[test_nr]));
+                }
                 /* Look for matchstring */
                 if (str_starts(line, matchstring))
+                {
                     iFound = eFoundAccountingStr;
+                }
                 break;
             case eFoundAccountingStr:
                 /* Already found matchstring - look for cycle data */
@@ -306,9 +320,13 @@ static int parse_logfile(const char *logfile, const char *errfile,
                     perfdata->ns_per_day[test_nr] = (ndum==5)? dum3 : dum1;
                     fclose(fp);
                     if (bResetChecked || presteps == 0)
+                    {
                         return eParselogOK;
+                    }
                     else
+                    {
                         return eParselogResetProblem;
+                    }
                 }
                 break;
         }
@@ -327,8 +345,10 @@ static int parse_logfile(const char *logfile, const char *errfile,
             if ( str_starts(line, "Fatal error:") )
             {
                 if (fgets(line, STRLEN, fp) != NULL)
+                {
                     fprintf(stderr, "\nWARNING: An error occured during this benchmark:\n"
                                     "%s\n", line);
+                }
                 fclose(fp);
                 cleandata(perfdata, test_nr);
                 return eParselogFatal;
@@ -379,7 +399,9 @@ static gmx_bool analyze_data(
         fprintf(fp, "Summary of successful runs:\n");
         fprintf(fp, "Line tpr PME nodes  Gcycles Av.     Std.dev.       ns/day        PME/f");
         if (nnodes > 1)
+        {
             fprintf(fp, "    DD grid");
+        }
         fprintf(fp, "\n");
     }
 
@@ -396,9 +418,13 @@ static gmx_bool analyze_data(
             pd->ns_per_day_Av = 0.0;
 
             if (pd->nPMEnodes == -1)
+            {
                 sprintf(strbuf, "(%3d)", pd->guessPME);
+            }
             else
+            {
                 sprintf(strbuf, "     ");
+            }
 
             /* Get the average run time of a setting */
             for (j=0; j<nrepeats; j++)
@@ -412,7 +438,9 @@ static gmx_bool analyze_data(
             for (j=0; j<nrepeats; j++)
             {
                 if (pd->ns_per_day[j] > 0.0)
+                {
                     pd->ns_per_day_Av += pd->ns_per_day[j];
+                }
                 else
                 {
                     /* Somehow the performance number was not aquired for this run,
@@ -425,9 +453,13 @@ static gmx_bool analyze_data(
 
             /* Nicer output: */
             if (pd->PME_f_load_Av > 0.0)
+            {
                 sprintf(str_PME_f_load, "%12.3f", pd->PME_f_load_Av);
+            }
             else
+            {
                 sprintf(str_PME_f_load, "%s", "         -  ");
+            }
 
 
             /* We assume we had a successful run if both averages are positive */
@@ -439,7 +471,9 @@ static gmx_bool analyze_data(
                     /* Calculate the standard deviation */
                     s = 0.0;
                     for (j=0; j<nrepeats; j++)
+                    {
                         s += pow( pd->Gcycles[j] - pd->Gcycles_Av, 2 );
+                    }
                     s /= (nrepeats - 1);
                     s = sqrt(s);
 
@@ -447,7 +481,9 @@ static gmx_bool analyze_data(
                             line, k, pd->nPMEnodes, strbuf, pd->Gcycles_Av, s,
                             pd->ns_per_day_Av, str_PME_f_load);
                     if (nnodes > 1)
+                    {
                         fprintf(fp, "  %3d %3d %3d", pd->nx, pd->ny, pd->nz);
+                    }
                     fprintf(fp, "\n");
                 }
                 /* Store the index of the best run found so far in 'winner': */
@@ -463,7 +499,9 @@ static gmx_bool analyze_data(
     }
 
     if (k_win == -1)
+    {
         gmx_fatal(FARGS, "None of the runs was successful! Check %s for problems.", fn);
+    }
 
     sep_line(fp);
 
@@ -478,13 +516,19 @@ static gmx_bool analyze_data(
     {
         /* We have optimized the number of PME-only nodes */
         if (winPME == -1)
+        {
             sprintf(strbuf, "%s", "the automatic number of PME nodes");
+        }
         else
+        {
             sprintf(strbuf, "%d PME nodes", winPME);
+        }
     }
     fprintf(fp, "Best performance was achieved with %s", strbuf);
     if ((nrepeats > 1) && (ntests > 1))
+    {
         fprintf(fp, " (see line %d)", line_win);
+    }
     fprintf(fp, "\n");
 
     /* Only mention settings if they were modified: */
@@ -505,17 +549,25 @@ static gmx_bool analyze_data(
     }
 
     if (bRefinedCoul)
+    {
         fprintf(fp, "   New Coulomb radius: %f nm (was %f nm)\n", info->rcoulomb[k_win], info->rcoulomb[0]);
+    }
 
     if (bRefinedVdW)
+    {
         fprintf(fp, "   New Van der Waals radius: %f nm (was %f nm)\n", info->rvdw[k_win], info->rvdw[0]);
+    }
 
     if (bRefinedGrid)
+    {
         fprintf(fp, "   New Fourier grid xyz: %d %d %d (was %d %d %d)\n", info->nkx[k_win], info->nky[k_win], info->nkz[k_win],
                                                                           info->nkx[0], info->nky[0], info->nkz[0]);
+    }
 
     if (bCanUseOrigTPR && ntprs > 1)
+    {
         fprintf(fp, "and original PME settings.\n");
+    }
 
     fflush(fp);
 
@@ -551,9 +603,13 @@ static void get_program_paths(gmx_bool bThreads, char *cmd_mpirun[], char cmd_np
     if (!bThreads)
     {
         if ( (cp = getenv("MPIRUN")) != NULL)
+        {
             *cmd_mpirun = strdup(cp);
+        }
         else
+        {
             *cmd_mpirun = strdup(def_mpirun);
+        }
     }
     else
     {
@@ -561,14 +617,20 @@ static void get_program_paths(gmx_bool bThreads, char *cmd_mpirun[], char cmd_np
     }
 
     if ( (cp = getenv("MDRUN" )) != NULL )
+    {
         *cmd_mdrun  = strdup(cp);
+    }
     else
+    {
         *cmd_mdrun  = strdup(def_mdrun);
+    }
 
 
     /* If no simulations have to be performed, we are done here */
     if (repeats <= 0)
+    {
         return;
+    }
 
     /* Run a small test to see whether mpirun + mdrun work  */
     fprintf(stdout, "Making sure that mdrun can be executed. ");
@@ -599,9 +661,13 @@ static void get_program_paths(gmx_bool bThreads, char *cmd_mpirun[], char cmd_np
         if (cp2!=NULL)
         {
             if ( str_starts(line, match_mdrun) )
+            {
                 bMdrun = TRUE;
+            }
             if ( str_starts(line, match_mpi) )
+            {
                 bMPI = TRUE;
+            }
         }
     }
     fclose(fp);
@@ -646,11 +712,10 @@ static void launch_simulation(
         FILE *fp,               /* General log file */
         gmx_bool bThreads,      /* whether to use threads */
         char *cmd_mpirun,       /* Command for mpirun */
-        char *cmd_np,           /* Switch for -np or -nt or empty */
+        char *cmd_np,           /* Switch for -np or -ntmpi or empty */
         char *cmd_mdrun,        /* Command for mdrun */
         char *args_for_mdrun,   /* Arguments for mdrun */
         const char *simulation_tpr,   /* This tpr will be simulated */
-        int  nnodes,            /* Number of nodes to run on */
         int  nPMEnodes)         /* Number of PME nodes to use */
 {
     char  *command;
@@ -727,7 +792,7 @@ static void make_benchmark_tprs(
         gmx_large_int_t statesteps, /* Step counter in checkpoint file               */
         real rmin,                  /* Minimal Coulomb radius                        */
         real rmax,                  /* Maximal Coulomb radius                        */
-       real bScaleRvdw,            /* Scale rvdw along with rcoulomb */
+        real bScaleRvdw,            /* Scale rvdw along with rcoulomb                */
         int *ntprs,                 /* No. of TPRs to write, each with a different
                                        rcoulomb and fourierspacing                   */
         t_inputinfo *info,          /* Contains information about mdp file options   */
@@ -763,8 +828,10 @@ static void make_benchmark_tprs(
 
     /* Check if some kind of PME was chosen */
     if (EEL_PME(ir->coulombtype) == FALSE)
+    {
         gmx_fatal(FARGS, "Can only do optimizations for simulations with %s electrostatics.",
                 EELTYPE(eelPME));
+    }
 
     /* Check if rcoulomb == rlist, which is necessary for plain PME. */
     if (  (ir->cutoff_scheme != ecutsVERLET) && 
@@ -801,7 +868,9 @@ static void make_benchmark_tprs(
     {
         box_size[d] = 0;
         for(i=0;i<DIM;i++)
+        {
             box_size[d] += state.box[d][i]*state.box[d][i];
+        }
         box_size[d] = sqrt(box_size[d]);
     }
 
@@ -843,11 +912,17 @@ static void make_benchmark_tprs(
             box_size[XX]/ir->nkx, box_size[YY]/ir->nky, box_size[ZZ]/ir->nkz);
     fprintf(fp, "   Van der Waals type   : %s\n", EVDWTYPE(ir->vdwtype));
     if (EVDW_SWITCHED(ir->vdwtype))
+    {
         fprintf(fp, "   rvdw_switch          : %f nm\n", ir->rvdw_switch);
+    }
     if (EPME_SWITCHED(ir->coulombtype))
+    {
         fprintf(fp, "   rlist                : %f nm\n", ir->rlist);
+    }
     if (ir->rlistlong != max_cutoff(ir->rvdw,ir->rcoulomb))
+    {
         fprintf(fp, "   rlistlong            : %f nm\n", ir->rlistlong);
+    }
 
     /* Print a descriptive line about the tpr settings tested */
     fprintf(fp, "\nWill try these real/reciprocal workload settings:\n");
@@ -855,11 +930,17 @@ static void make_benchmark_tprs(
     fprintf(fp, "  nkx  nky  nkz");
     fprintf(fp, "   spacing");
     if (evdwCUT == ir->vdwtype)
+    {
         fprintf(fp, "      rvdw");
+    }
     if (EPME_SWITCHED(ir->coulombtype))
+    {
         fprintf(fp, "     rlist");
+    }
     if ( ir->rlistlong != max_cutoff(ir->rlist,max_cutoff(ir->rvdw,ir->rcoulomb)) )
+    {
         fprintf(fp, " rlistlong");
+    }
     fprintf(fp, "  tpr file\n");
 
     /* Loop to create the requested number of tpr input files */
@@ -935,9 +1016,13 @@ static void make_benchmark_tprs(
         fprintf(stdout,"Writing benchmark tpr %s with nsteps=", fn_bench_tprs[j]);
         fprintf(stdout, gmx_large_int_pfmt, ir->nsteps);
         if (j > 0)
+        {
             fprintf(stdout,", scaling factor %f\n", fac);
+        }
         else
+        {
             fprintf(stdout,", unmodified settings\n");
+        }
 
         write_tpx_state(fn_bench_tprs[j],ir,&state,&mtop);
 
@@ -946,11 +1031,17 @@ static void make_benchmark_tprs(
         fprintf(fp, "%5d%5d%5d", ir->nkx, ir->nky, ir->nkz);
         fprintf(fp, " %9f ", info->fsx[j]);
         if (evdwCUT == ir->vdwtype)
+        {
             fprintf(fp, "%10f", ir->rvdw);
+        }
         if (EPME_SWITCHED(ir->coulombtype))
+        {
             fprintf(fp, "%10f", ir->rlist);
+        }
         if ( info->rlistlong[0] != max_cutoff(info->rlist[0],max_cutoff(info->rvdw[0],info->rcoulomb[0])) )
+        {
             fprintf(fp, "%10f", ir->rlistlong);
+        }
         fprintf(fp, "  %-14s\n",fn_bench_tprs[j]);
 
         /* Make it clear to the user that some additional settings were modified */
@@ -961,9 +1052,11 @@ static void make_benchmark_tprs(
         }
     }
     if (bNote)
+    {
         fprintf(fp, "\nNote that in addition to the Coulomb radius and the Fourier grid\n"
                     "other input settings were also changed (see table above).\n"
                     "Please check if the modified settings are appropriate.\n");
+    }
     fflush(stdout);
     fflush(fp);
     sfree(ir);
@@ -997,7 +1090,9 @@ static void cleanup(const t_filenm *fnm, int nfile, int k, int nnodes,
             /* Give the log file a nice name so one can later see which parameters were used */
             numstring[0] = '\0';
             if (nr > 0)
+            {
                 sprintf(numstring, "_%d", nr);
+            }
             sprintf(newfilename, "%s_no%d_np%d_npme%d%s", opt2fn("-bg",nfile,fnm), k, nnodes, nPMEnodes, numstring);
             if (gmx_fexist(opt2fn("-bg",nfile,fnm)))
             {
@@ -1013,7 +1108,9 @@ static void cleanup(const t_filenm *fnm, int nfile, int k, int nnodes,
             fn = opt2fn(opt, nfile, fnm);
             numstring[0] = '\0';
             if (nr > 0)
+            {
                 sprintf(numstring, "_%d", nr);
+            }
             sprintf(newfilename, "%s_no%d_np%d_npme%d%s", fn, k, nnodes, nPMEnodes, numstring);
             if (gmx_fexist(fn))
             {
@@ -1093,11 +1190,17 @@ static void make_npme_list(
     else /* "auto" or "range" */
     {
         if (nnodes <= 64)
+        {
             eNPME = eNpmeAll;
+        }
         else if (nnodes < 128)
+        {
             eNPME = eNpmeReduced;
+        }
         else
+        {
             eNPME = eNpmeSubset;
+        }
     }
 
     /* Calculate how many entries we could possibly have (in case of -npme all) */
@@ -1105,10 +1208,14 @@ static void make_npme_list(
     {
         nlistmax = maxPMEnodes - minPMEnodes + 3;
         if (0 == minPMEnodes)
+        {
             nlistmax--;
+        }
     }
     else
+    {
         nlistmax = 1;
+    }
 
     /* Now make the actual list which is at most of size nlist */
     snew(*nPMEnodes, nlistmax);
@@ -1147,7 +1254,9 @@ static void make_npme_list(
 
     fprintf(stderr, "Will try the following %d different values for -npme:\n", *nentries);
     for (i=0; i<*nentries-1; i++)
+    {
         fprintf(stderr, "%d, ", (*nPMEnodes)[i]);
+    }
     fprintf(stderr, "and %d (auto).\n", (*nPMEnodes)[*nentries-1]);
 }
 
@@ -1229,7 +1338,6 @@ static void do_the_tests(
         char *cmd_args_bench,       /* arguments for mdrun in a string        */
         const t_filenm *fnm,        /* List of filenames from command line    */
         int nfile,                  /* Number of files specified on the cmdl. */
-        int sim_part,               /* For checkpointing                      */
         int presteps,               /* DLB equilibration steps, is checked    */
         gmx_large_int_t cpt_steps)  /* Time step counter in the checkpoint    */
 {
@@ -1330,14 +1438,20 @@ static void do_the_tests(
                 /* To prevent that all benchmarks fail due to a show-stopper argument
                  * on the mdrun command line, we make a quick check with mdrun -h first */
                 if (bFirst)
+                {
                     make_sure_it_runs(pd->mdrun_cmd_line, cmdline_length, fp);
+                }
                 bFirst = FALSE;
 
                 /* Do a benchmark simulation: */
                 if (repeats > 1)
+                {
                     sprintf(buf, ", pass %d/%d", nr+1, repeats);
+                }
                 else
+                {
                     buf[0]='\0';
+                }
                 fprintf(stdout, "\n=== Progress %2.0f%%, tpr %d/%d, run %d/%d%s:\n",
                         (100.0*count)/totaltests,
                         k+1, nr_tprs, i+1, *pmeentries, buf);
@@ -1351,24 +1465,36 @@ static void do_the_tests(
                 ret = parse_logfile(opt2fn("-bg",nfile,fnm), opt2fn("-err",nfile,fnm),
                         pd, nr, presteps, cpt_steps, nnodes);
                 if ((presteps > 0) && (ret == eParselogResetProblem))
+                {
                     bResetProblem = TRUE;
+                }
 
                 if (-1 == pd->nPMEnodes)
+                {
                     sprintf(buf, "(%3d)", pd->guessPME);
+                }
                 else
+                {
                     sprintf(buf, "     ");
+                }
 
                 /* Nicer output */
                 if (pd->PME_f_load[nr] > 0.0)
+                {
                     sprintf(str_PME_f_load, "%12.3f", pd->PME_f_load[nr]);
+                }
                 else
+                {
                     sprintf(str_PME_f_load, "%s", "         -  ");
+                }
 
                 /* Write the data we got to disk */
                 fprintf(fp, "%4d%s %12.3f %12.3f %s    %s", pd->nPMEnodes,
                         buf, pd->Gcycles[nr], pd->ns_per_day[nr], str_PME_f_load, ParseLog[ret]);
                 if (! (ret==eParselogOK || ret==eParselogNoDDGrid || ret==eParselogNotFound) )
+                {
                     fprintf(fp, " Check %s file for problems.", ret==eParselogFatal? "err":"log");
+                }
                 fprintf(fp, "\n");
                 fflush(fp);
                 count++;
@@ -1421,26 +1547,36 @@ static void check_input(
 
     /* Make sure the input file exists */
     if (!gmx_fexist(opt2fn("-s",nfile,fnm)))
+    {
         gmx_fatal(FARGS, "File %s not found.", opt2fn("-s",nfile,fnm));
+    }
 
     /* Make sure that the checkpoint file is not overwritten during benchmarking */
     if ( (0 == strcmp(opt2fn("-cpi",nfile,fnm), opt2fn("-bcpo",nfile,fnm)) ) && (sim_part > 1) )
+    {
         gmx_fatal(FARGS, "Checkpoint input (-cpi) and benchmark checkpoint output (-bcpo) files must not be identical.\n"
                          "The checkpoint input file must not be overwritten during the benchmarks.\n");
+    }
 
     /* Make sure that repeats is >= 0 (if == 0, only write tpr files) */
     if (repeats < 0)
+    {
         gmx_fatal(FARGS, "Number of repeats < 0!");
+    }
 
     /* Check number of nodes */
     if (nnodes < 1)
+    {
         gmx_fatal(FARGS, "Number of nodes/threads must be a positive integer.");
+    }
 
     /* Automatically choose -ntpr if not set */
     if (*ntprs < 1)
     {
         if (nnodes < 16)
+        {
             *ntprs = 1;
+        }
         else
         {
             *ntprs = 3;
@@ -1453,12 +1589,20 @@ static void check_input(
     else
     {
         if (1 == *ntprs)
+        {
             fprintf(stderr, "Note: Choose ntpr>1 to shift PME load between real and reciprocal space.\n");
+        }
     }
 
     /* Make shure that rmin <= rcoulomb <= rmax */
-    if (*rmin <= 0) *rmin = rcoulomb;
-    if (*rmax <= 0) *rmax = rcoulomb;
+    if (*rmin <= 0)
+    {
+        *rmin = rcoulomb;
+    }
+    if (*rmax <= 0)
+    {
+        *rmax = rcoulomb;
+    }
     if ( !(*rmin <= *rmax) )
     {
         gmx_fatal(FARGS, "Please choose the Coulomb radii such that rmin <= rmax.\n"
@@ -1483,11 +1627,15 @@ static void check_input(
     old = *ntprs;
     /* If one of rmin, rmax is set, we need 2 tpr files at minimum */
     if ( !is_equal(*rmax, rcoulomb) || !is_equal(*rmin, rcoulomb) )
+    {
         *ntprs = max(*ntprs, 2);
+    }
 
     /* If both rmin, rmax are set, we need 3 tpr files at minimum */
     if ( !is_equal(*rmax, rcoulomb) && !is_equal(*rmin, rcoulomb) )
+    {
         *ntprs = max(*ntprs, 3);
+    }
 
     if (old != *ntprs)
     {
@@ -1507,15 +1655,23 @@ static void check_input(
 
     /* Check whether max and min fraction are within required values */
     if (maxPMEfraction > 0.5 || maxPMEfraction < 0)
+    {
         gmx_fatal(FARGS, "-max must be between 0 and 0.5");
+    }
     if (minPMEfraction > 0.5 || minPMEfraction < 0)
+    {
         gmx_fatal(FARGS, "-min must be between 0 and 0.5");
+    }
     if (maxPMEfraction < minPMEfraction)
+    {
         gmx_fatal(FARGS, "-max must be larger or equal to -min");
+    }
 
     /* Check whether the number of steps - if it was set - has a reasonable value */
     if (bench_nsteps < 0)
+    {
         gmx_fatal(FARGS, "Number of steps must be positive.");
+    }
 
     if (bench_nsteps > 10000 || bench_nsteps < 100)
     {
@@ -1533,7 +1689,9 @@ static void check_input(
     if (*ntprs > 1)
     {
         if (*rmin/rcoulomb < 0.75 || *rmax/rcoulomb > 1.25)
+        {
             fprintf(stderr, "WARNING: Applying extreme scaling factor. I hope you know what you are doing.\n");
+        }
     }
 
     /* If a fixed number of PME nodes is set we do rcoulomb and PME gird tuning
@@ -1580,23 +1738,39 @@ static gmx_bool is_bench_file(char *opt, gmx_bool bSet, gmx_bool bOptional, gmx_
 {
     /* Apart from the input .tpr, all files starting with "-b" are for
      * _b_enchmark files exclusively */
-    if (0 == strncmp(opt,"-s", 2)) return FALSE;
+    if (0 == strncmp(opt,"-s", 2))
+    {
+        return FALSE;
+    }
+
     if (0 == strncmp(opt,"-b", 2) || 0 == strncmp(opt,"-s", 2))
     {
         if (!bOptional || bSet)
+        {
             return TRUE;
+        }
         else
+        {
             return FALSE;
+        }
     }
     else
     {
         if (bIsOutput)
+        {
             return FALSE;
+        }
         else
+        {
             if (bSet) /* These are additional input files like -cpi -ei */
+            {
                 return TRUE;
+            }
             else
+            {
                 return FALSE;
+            }
+        }
     }
 }
 
@@ -1615,17 +1789,12 @@ static void add_to_string(char **str, char *buf)
 
 /* Create the command line for the benchmark as well as for the real run */
 static void create_command_line_snippets(
-        gmx_bool bThreads,
         gmx_bool bAppendFiles,
         gmx_bool bKeepAndNumCPT,
         gmx_bool bResetHWay,
         int      presteps,
         int      nfile,
         t_filenm fnm[],
-        int      npargs,
-        t_pargs  *pa,
-        const char *procstring,      /* How to pass the number of processors to $MPIRUN */
-        char     *cmd_np[],          /* Actual command line snippet, e.g. '-np <N>' */
         char     *cmd_args_bench[],  /* command line arguments for benchmark runs */
         char     *cmd_args_launch[], /* command line arguments for simulation run */
         char     extra_args[])       /* Add this to the end of the command line */
@@ -1682,13 +1851,17 @@ static void create_command_line_snippets(
             /* All options starting with -b* need the 'b' removed,
              * therefore overwrite strbuf */
             if (0 == strncmp(opt, "-b", 2))
+            {
                 sprintf(strbuf, "-%s %s ", &opt[2], name);
+            }
 
             add_to_string(cmd_args_bench, strbuf);
         }
 
         if ( is_launch_file(opt,opt2bSet(opt,nfile,fnm)) )
+        {
             add_to_string(cmd_args_launch, strbuf);
+        }
     }
 
     add_to_string(cmd_args_bench , extra_args);
@@ -1699,11 +1872,15 @@ static void create_command_line_snippets(
 /* Set option opt */
 static void setopt(const char *opt,int nfile,t_filenm fnm[])
 {
-  int i;
+    int i;
 
-  for(i=0; (i<nfile); i++)
-    if (strcmp(opt,fnm[i].opt)==0)
-      fnm[i].flag |= ffSET;
+    for(i=0; (i<nfile); i++)
+    {
+        if (strcmp(opt,fnm[i].opt)==0)
+        {
+            fnm[i].flag |= ffSET;
+        }
+    }
 }
 
 
@@ -1815,7 +1992,7 @@ static double gettime()
 int gmx_tune_pme(int argc,char *argv[])
 {
     const char *desc[] = {
-            "For a given number [TT]-np[tt] or [TT]-nt[tt] of processors/threads, this program systematically",
+            "For a given number [TT]-np[tt] or [TT]-ntmpi[tt] of processors/threads, this program systematically",
             "times [TT]mdrun[tt] with various numbers of PME-only nodes and determines",
             "which setting is fastest. It will also test whether performance can",
             "be enhanced by shifting load from the reciprocal to the real space",
@@ -1830,7 +2007,7 @@ int gmx_tune_pme(int argc,char *argv[])
             "[TT]export MPIRUN=\"/usr/local/mpirun -machinefile hosts\"[tt][PAR]",
             "Please call [TT]g_tune_pme[tt] with the normal options you would pass to",
             "[TT]mdrun[tt] and add [TT]-np[tt] for the number of processors to perform the",
-            "tests on, or [TT]-nt[tt] for the number of threads. You can also add [TT]-r[tt]",
+            "tests on, or [TT]-ntmpi[tt] for the number of threads. You can also add [TT]-r[tt]",
             "to repeat each test several times to get better statistics. [PAR]",
             "[TT]g_tune_pme[tt] can test various real space / reciprocal space workloads",
             "for you. With [TT]-ntpr[tt] you control how many extra [TT].tpr[tt] files will be",
@@ -1988,8 +2165,8 @@ int gmx_tune_pme(int argc,char *argv[])
         "Number of nodes to run the tests on (must be > 2 for separate PME nodes)" },
       { "-npstring", FALSE, etENUM, {procstring},
         "Specify the number of processors to [TT]$MPIRUN[tt] using this string"},
-      { "-nt",       FALSE, etINT,  {&nthreads},
-        "Number of threads to run the tests on (turns MPI & mpirun off)"},
+      { "-ntmpi",    FALSE, etINT,  {&nthreads},
+        "Number of MPI-threads to run the tests on (turns MPI & mpirun off)"},
       { "-r",        FALSE, etINT,  {&repeats},
         "Repeat each test this often" },
       { "-max",      FALSE, etREAL, {&maxPMEfraction},
@@ -2054,14 +2231,18 @@ int gmx_tune_pme(int argc,char *argv[])
         add_to_string(&ExtraArgs, " ");
     }
 
-    if (opt2parg_bSet("-nt",asize(pa),pa))
+    if (opt2parg_bSet("-ntmpi",asize(pa),pa))
     {
         bThreads=TRUE;
         if (opt2parg_bSet("-npstring",asize(pa),pa))
+        {
             fprintf(stderr, "WARNING: -npstring has no effect when using threads.\n");
+        }
 
         if (nnodes > 1)
+        {
             gmx_fatal(FARGS, "Can't run multi-threaded MPI simulation yet!");
+        }
         /* and now we just set this; a bit of an ugly hack*/
         nnodes=nthreads;
     }
@@ -2074,16 +2255,18 @@ int gmx_tune_pme(int argc,char *argv[])
     /* Construct the command line arguments for benchmark runs
      * as well as for the simulation run */
     if (bThreads)
-        sprintf(bbuf," -nt %d ", nthreads);
+    {
+        sprintf(bbuf," -ntmpi %d ", nthreads);
+    }
     else
+    {
         sprintf(bbuf," -np %d ", nnodes);
+    }
 
     cmd_np = bbuf;
 
-    create_command_line_snippets(bThreads,bAppendFiles,bKeepAndNumCPT,bResetCountersHalfWay,presteps,
-                                 NFILE,fnm,asize(pa),pa,procstring[0],
-                                 &cmd_np, &cmd_args_bench, &cmd_args_launch,
-                                 ExtraArgs);
+    create_command_line_snippets(bAppendFiles,bKeepAndNumCPT,bResetCountersHalfWay,presteps,
+                                 NFILE,fnm,&cmd_args_bench, &cmd_args_launch, ExtraArgs);
 
     /* Read in checkpoint file if requested */
     sim_part = 1;
@@ -2098,7 +2281,9 @@ int gmx_tune_pme(int argc,char *argv[])
         sim_part++;
         /* sim_part will now be 1 if no checkpoint file was found */
         if (sim_part<=1)
+        {
             gmx_fatal(FARGS, "Checkpoint file %s not found!", opt2fn("-cpi",NFILE,fnm));
+        }
     }
 
     /* Open performance output file and write header info */
@@ -2139,7 +2324,9 @@ int gmx_tune_pme(int argc,char *argv[])
             minPMEnodes = max(floor(minPMEfraction*nnodes), 0);
             fprintf(stdout, "Will try runs with %d ", minPMEnodes);
             if (maxPMEnodes != minPMEnodes)
+            {
                 fprintf(stdout, "- %d ", maxPMEnodes);
+            }
             fprintf(stdout, "PME-only nodes.\n  Note that the automatic number of PME-only nodes and no separate PME nodes are always tested.\n");
         }
     }
@@ -2162,12 +2349,18 @@ int gmx_tune_pme(int argc,char *argv[])
         fprintf(fp, "Number of nodes         : %d\n", nnodes);
         fprintf(fp, "The mpirun command is   : %s\n", cmd_mpirun);
         if ( strcmp(procstring[0], "none") != 0)
+        {
             fprintf(fp, "Passing # of nodes via  : %s\n", procstring[0]);
+        }
         else
+        {
             fprintf(fp, "Not setting number of nodes in system call\n");
+        }
     }
     else
+    {
         fprintf(fp, "Number of threads       : %d\n", nnodes);
+    }
 
     fprintf(fp, "The mdrun  command is   : %s\n", cmd_mdrun);
     fprintf(fp, "mdrun args benchmarks   : %s\n", cmd_args_bench);
@@ -2223,12 +2416,14 @@ int gmx_tune_pme(int argc,char *argv[])
     /* Make alternative tpr files to test: */
     snew(tpr_names, ntprs);
     for (i=0; i<ntprs; i++)
+    {
         snew(tpr_names[i], STRLEN);
+    }
 
     /* It can be that ntprs is reduced by make_benchmark_tprs if not enough
      * different grids could be found. */
     make_benchmark_tprs(opt2fn("-s",NFILE,fnm), tpr_names, bench_nsteps+presteps,
-                       cpt_steps, rmin, rmax, bScaleRvdw, &ntprs, info, fp);
+            cpt_steps, rmin, rmax, bScaleRvdw, &ntprs, info, fp);
 
     /********************************************************************************/
     /* Main loop over all scenarios we need to test: tpr files, PME nodes, repeats  */
@@ -2238,7 +2433,7 @@ int gmx_tune_pme(int argc,char *argv[])
     {
         do_the_tests(fp, tpr_names, maxPMEnodes, minPMEnodes, npme_fixed, npmevalues_opt[0], perfdata, &pmeentries,
                 repeats, nnodes, ntprs, bThreads, cmd_mpirun, cmd_np, cmd_mdrun,
-                cmd_args_bench, fnm, NFILE, sim_part, presteps, cpt_steps);
+                cmd_args_bench, fnm, NFILE, presteps, cpt_steps);
 
         fprintf(fp, "\nTuning took%8.1f minutes.\n", (gettime()-seconds)/60.0);
 
@@ -2267,13 +2462,15 @@ int gmx_tune_pme(int argc,char *argv[])
 
         /* Now start the real simulation if the user requested it ... */
         launch_simulation(bLaunch, fp, bThreads, cmd_mpirun, cmd_np, cmd_mdrun,
-                cmd_args_launch, simulation_tpr, nnodes, best_npme);
+                cmd_args_launch, simulation_tpr, best_npme);
     }
     ffclose(fp);
 
     /* ... or simply print the performance results to screen: */
     if (!bLaunch)
+    {
         finalize(opt2fn("-p", NFILE, fnm));
+    }
 
     return 0;
 }
index dd65ebeccb21d00d17e5d396f22a94a10bda3542..47f123b3d45199da7bb910f787e0dcd91a4c033e 100644 (file)
@@ -1,3 +1,155 @@
-add_test(NAME TestExec_mdrun-h
-         COMMAND mdrun -h)
-add_dependencies(tests mdrun)
+#
+# This file is part of the GROMACS molecular simulation package.
+#
+# Copyright (c) 2012, by the GROMACS development team, led by
+# David van der Spoel, Berk Hess, 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.
+#
+set(REGRESSIONTEST_PATH "" CACHE PATH "Directory containing regressiontests")
+mark_as_advanced(REGRESSIONTEST_PATH)
+option(REGRESSIONTEST_DOWNLOAD
+    "Automatically download regressiontests. Tests can be run with ctest." no)
+if(REGRESSIONTEST_DOWNLOAD AND CMAKE_VERSION VERSION_LESS "2.8.2")
+    message(WARNING "REGRESSIONTEST_DOWNLOAD requires cmake >=2.8.2. Please update cmake or manually download the regressiontests.")
+    set(REGRESSIONTEST_DOWNLOAD FALSE CACHE BOOL 
+        "REGRESSIONTEST_DOWNLOAD not supported with cmake ${CMAKE_VERSION}" FORCE)
+endif()
+if(REGRESSIONTEST_DOWNLOAD)
+    if("${PROJECT_VERSION}" MATCHES "-dev")
+        set(REGRESSIONTEST_VERSION master)
+    else()
+        set(REGRESSIONTEST_VERSION ${PROJECT_VERSION})
+    endif()
+    set(REGRESSIONTEST_URL
+        http://gerrit.gromacs.org/download/regressiontests-${REGRESSIONTEST_VERSION}.tar.gz)
+    set(REGRESSIONTEST_FILE "${CMAKE_CURRENT_BINARY_DIR}/regressiontests.tgz")
+    message("Downloading: ${REGRESSIONTEST_URL}")
+    file(DOWNLOAD ${REGRESSIONTEST_URL} "${REGRESSIONTEST_FILE}" SHOW_PROGRESS STATUS status LOG log)
+    list(GET status 0 status_code)
+    list(GET status 1 status_string)
+    
+    if(NOT status_code EQUAL 0)
+        message(FATAL_ERROR "error: downloading '${REGRESSIONTEST_URL}' failed
+status_code: ${status_code}
+status_string: ${status_string}
+log: ${log}")
+    endif()
+
+    set(REGRESSIONTEST_PATH
+        "${CMAKE_CURRENT_BINARY_DIR}/regressiontests-${REGRESSIONTEST_VERSION}"
+        CACHE PATH "Path to auto-downloaded regressiontests" FORCE)
+    file(REMOVE_RECURSE "${REGRESSIONTEST_PATH}") #delete potential prior folder
+    execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf "${REGRESSIONTEST_FILE}"
+        WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
+    if(NOT EXISTS ${REGRESSIONTEST_PATH}/gmxtest.pl)
+        message(FATAL_ERROR "Download incorrect. Doesn't contain required gmxtest.pl")
+    endif()
+    set(REGRESSIONTEST_DOWNLOAD OFF CACHE BOOL "Tests already downloaded. Set to yes to download again" FORCE)
+endif()
+
+if(REGRESSIONTEST_PATH AND (GMX_BLUEGENE OR CMAKE_CROSSCOMPILING OR CMAKE_CONFIGURATION_TYPES))
+    #Bluegene requires us to compile both front-end and back-end binaries (single build is insufficient)
+    message(WARNING 
+        "With cross-compiling or multi-configuration generators (e.g. Visual Studio), running regressiontests from build system is not supported. Please run gmxtest.pl directly.")
+    set(REGRESSIONTEST_PATH OFF CACHE BOOL 
+        "With cross-compiling or multi-configuration generators, running regressiontests from build system is not supported." FORCE)
+endif()
+
+if(REGRESSIONTEST_PATH)
+    if(NOT EXISTS ${REGRESSIONTEST_PATH}/gmxtest.pl)
+        message(FATAL_ERROR
+            "REGRESSIONTEST_PATH invalid. The path needs to contain gmxtest.pl.")
+    endif()
+    if(GMX_DOUBLE)
+        list(APPEND ARGS -double)
+    endif()
+    if(GMX_LIB_MPI AND NOT MPIEXEC) #autodetection failed or CC=mpicc was used
+        message(WARNING
+            "Please set MPIEXEC. Otherwise mpirun is assumed for runnings tests.")
+    endif()
+    if(GMX_LIB_MPI)
+        set(GMX_TEST_NUMBER_PROCS 8 CACHE STRING "Number of processors used for testing")
+        mark_as_advanced(GMX_TEST_NUMBER_PROCS)
+        list(APPEND ARGS -np ${GMX_TEST_NUMBER_PROCS})
+        if(MPIEXEC)
+            list(APPEND ARGS -mpirun ${MPIEXEC})
+        endif()
+        #We should use MPIEXEC_NUMPROC_FLAG but gmxtest.pl doesn't let us pass it
+    endif()
+    if(GMX_BINARY_SUFFIX)
+        list(APPEND ARGS -suffix ${GMX_BINARY_SUFFIX})
+    endif()
+    #crosscompile is only used to disable checking whether binaries work
+    #given that we know they are there and that mdrun might not be exectuable
+    #(e.g. Cray) we enable it.
+    list(APPEND ARGS -crosscompile)
+
+    set(REGRESSIONTEST_EXTRA_ARGS "" CACHE STRING 
+        "Extra arguments passed to gmxtest")
+    mark_as_advanced(REGRESSIONTEST_EXTRA_ARGS)
+    list(APPEND ARGS ${REGRESSIONTEST_EXTRA_ARGS})
+
+    list(APPEND ARGS -noverbose -nosuffix)
+
+    if(GMX_NATIVE_WINDOWS)
+        set(PATH_SEPARATOR "\\;")
+        #replacing \ with / shouldn't be neccessary. But otherwise "..\bin\;c:\.."
+        #gets turned into "...\bin\\c:\.." don't know why and don't have a better
+        #workaround. This workaround doesn't hurt.
+        string(REPLACE "\\" "/" PATH "$ENV{PATH}")
+        #protect ; (don't treat as list)
+        string(REPLACE ";" "\\;" PATH "${PATH}")
+    else()
+        set(PATH_SEPARATOR ":")
+        set(PATH "$ENV{PATH}")
+    endif()
+
+    foreach(FOLDER bin lib) #lib folders might be needed for
+        #e.g. DLLs. For GMX paths native ("\") is needed for GMXLIB detection
+        file(TO_NATIVE_PATH "${CMAKE_BINARY_DIR}/${FOLDER}" DIR)
+        set(PATH "${DIR}${PATH_SEPARATOR}${PATH}")
+    endforeach()
+
+    find_program(PERL_EXECUTABLE NAMES "perl")
+    mark_as_advanced(PERL_EXECUTABLE)
+
+    if (NOT PERL_EXECUTABLE)
+        message(FATAL_ERROR "Perl not found. Install perl, set PERL_EXECUTABLE to the perl location, or unset REGRESSIONTEST_PATH to disable testing.")
+    endif()
+
+    #currently not testing tools because they don't contain any useful tests
+    foreach(subtest simple complex kernel freeenergy pdb2gmx)
+        add_test(NAME regressiontests/${subtest}
+            #windows requires the command to be perl and not the script
+            COMMAND perl "${REGRESSIONTEST_PATH}/gmxtest.pl" ${subtest} ${ARGS})
+        set_tests_properties(regressiontests/${subtest} PROPERTIES
+            ENVIRONMENT "PATH=${PATH}")
+    endforeach()
+endif()