mark_as_advanced(GMX_FAHCORE)
option(GMX_OPENMM "Accelerated execution on GPUs through the OpenMM library (rerun cmake after changing to see relevant options)" OFF)
set(GMX_ACCELERATION "auto"
- CACHE STRING "Accelerated kernels. Pick one of: auto, none, SSE, BlueGene, Power6, ia64, altivec")
+ CACHE STRING "Accelerated kernels. Pick one of: auto, none, SSE, BlueGene, Power6, ia64, altivec, fortran")
set(GMX_FFT_LIBRARY "fftw3"
CACHE STRING "FFT library choices: fftw3,fftw2,mkl,fftpack[built-in]")
mark_as_advanced(USE_VERSION_H)
option(GMX_DEFAULT_SUFFIX "Use default suffixes for GROMACS binaries and libs (_d for double, _mpi for MPI; rerun cmake after changing to see relevant options)" ON)
+
+########################################################################
+# Set up binary and library suffixing
+########################################################################
set(GMX_BINARY_SUFFIX "" CACHE STRING "Suffix for GROMACS binaries (default: _d for double, _mpi for MPI, _mpi_d for MPI and double).")
set(GMX_LIBS_SUFFIX ""
CACHE STRING "Suffix for GROMACS libs (default: _d for double, _mpi for MPI, _mpi_d for MPI and double).")
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 "-gpu")
+ set (GMX_LIBS_SUFFIX "_gpu")
+ endif(GMX_OPENMM)
mark_as_advanced(FORCE GMX_BINARY_SUFFIX GMX_LIBS_SUFFIX)
message(STATUS "Using default binary suffix: \"${GMX_BINARY_SUFFIX}\"")
message(STATUS "Using default library suffix: \"${GMX_LIBS_SUFFIX}\"")
set(PKG_CFLAGS "")
if(GMX_DOUBLE)
- set(PKG_CFLAGS "${PKG_CFLAGS} -DGMX_DOUBLE")
+ set(PKG_CFLAGS "${PKG_CFLAGS} -DGMX_DOUBLE")
endif(GMX_DOUBLE)
if(GMX_SOFTWARE_INVSQRT)
set(PKG_CFLAGS "${PKG_CFLAGS} -DGMX_SOFTWARE_INVSQRT")
if(GMX_OPENMM)
cmake_minimum_required(VERSION 2.6.4)
# we'll use the built-in fft to avoid unnecessary dependencies
- message(STATUS "No external FFT libraries needed for the OpenMM build, using fftpack!")
- set (GMX_FFT_LIBRARY "fftpack" CACHE STRING
- "No external FFT libraries needed for the OpenMM build, using fftpack!" FORCE)
+ 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_THREADS)
- message(STATUS "Threads not compatible with OpenMM build, disabled!")
+ message(STATUS "Threads are not compatible with OpenMM build, disabled!")
set(GMX_THREADS OFF CACHE BOOL
- "Threads not compatible with OpenMM build, disabled!" FORCE)
+ "Threads are not compatible with OpenMM build, disabled!" FORCE)
endif(GMX_THREADS)
if(GMX_SOFTWARE_INVSQRT)
- set(GMX_SOFTWARE_INVSQRT OFF FORCE)
+ set(GMX_SOFTWARE_INVSQRT OFF CACHE STRING
+ "The OpenMM build does not need GROMACS software 1/sqrt!" FORCE)
endif(GMX_SOFTWARE_INVSQRT)
- if(NOT GMX_ACCELERATION MATCHES "^(none|None|NONE)")
- message(WARNING "CPU-based acceleration turned off, OpenMM does not support/need any!")
- unset(GMX_ACCELERATION CACHE)
+ string(TOUPPER ${GMX_ACCELERATION} GMX_ACCELERATION)
+ if(NOT GMX_ACCELERATION STREQUAL "NONE")
+ message(STATUS "Switching off CPU-based acceleration, the OpenMM build does not support/need any!")
set(GMX_ACCELERATION "none" CACHE STRING
- "CPU-based acceleration turned off, OpenMM does not support/need any!" FORCE)
+ "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)
- set(GMX_DOUBLE OFF FORCE )
+ 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_ACCELERATION GMX_MPI GMX_FFT_LIBRARY
GMX_QMMM_PROGRAM GMX_THREADS GMX_DOUBLE)
if (${GMX_ACCELERATION} STREQUAL "auto" AND NOT GMX_OPENMM)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(i.86|x86|x64|x86_64|AMD64|amd64)")
- set(GMX_ACCELERATION "SSE" CACHE STRING "Accelerated kernels. Pick one of: auto, none, SSE, BlueGene, Power6, ia64, altivec" FORCE)
+ set(GMX_ACCELERATION "SSE" CACHE STRING "Accelerated kernels. Pick one of: auto, none, SSE, BlueGene, Power6, ia64, altivec, fortran" FORCE)
if (GMX_64_BIT)
set(GMX_X86_64_ASM ON CACHE BOOL "Add SSE assembly files for x86_64" FORCE)
# Determine the assembler/compiler to use
else()
- set(GMX_ACCELERATION "none" CACHE STRING "Accelerated kernels. Pick one of: auto, none, SSE, BlueGene, Power6, ia64, altivec" FORCE)
+ set(GMX_ACCELERATION "none" CACHE STRING "Accelerated kernels. Pick one of: auto, none, SSE, BlueGene, Power6, ia64, altivec, fortran" FORCE)
endif()
endif (${GMX_ACCELERATION} STREQUAL "auto" AND NOT GMX_OPENMM)
set(PKG_CFLAGS "${PKG_CFLAGS} -DGMX_INTERNAL_XDR")
endif(NOT GMX_SYSTEM_XDR)
-if(GMX_FORTRAN OR GMX_POWER6)
- enable_language(Fortran)
- include(FortranCInterface)
- discover_fortran_mangling(prefix isupper suffix extra_under_score found)
- if(extra_under_score)
- set(extrasuffix "_")
- endif(extra_under_score)
-
- if(isupper)
- set(F77_FUNCDEF "${prefix} ## NAME ## ${suffix}")
- set(F77_FUNCDEF_ "${prefix} ## NAME ## ${suffix}${extrasuffix}")
- else(isupper)
- set(F77_FUNCDEF "${prefix} ## name ## ${suffix}")
- set(F77_FUNCDEF_ "${prefix} ## name ## ${suffix}${extrasuffix}")
- endif(isupper)
-else(GMX_FORTRAN OR GMX_POWER6)
- set(F77_FUNCDEF "name ## _")
- set(F77_FUNCDEF_ "name ## _")
-endif(GMX_FORTRAN OR GMX_POWER6)
-
-
# Process nonbonded accelerated kernels settings
string(TOUPPER ${GMX_ACCELERATION} ${GMX_ACCELERATION})
if(${GMX_ACCELERATION} STREQUAL "NONE")
if(GMX_DOUBLE)
set(GMX_IA32_SSE2 1)
else()
- set(GMX_IA32_SSE 1)
+ set(GMX_IA32_SSE 1)
endif()
elseif(GMX_X86_64_ASM)
if(GMX_DOUBLE)
- set(GMX_X86_64_SSE2 1)
+ set(GMX_X86_64_SSE2 1)
else()
set(GMX_X86_64_SSE 1)
endif()
elseif(${GMX_ACCELERATION} STREQUAL "FORTRAN")
set(GMX_FORTRAN 1)
+ #these are switch on by default sometimes
+ set(GMX_IA32_ASM 0)
+ set(GMX_GMX_X86_64_ASM 0)
elseif(${GMX_ACCELERATION} STREQUAL "BLUEGENE")
set(GMX_BLUEGENE 1)
elseif(${GMX_ACCELERATION} STREQUAL "POWER6")
MESSAGE(FATAL_ERROR "Unrecognized option for accelerated kernels: ${GMX_ACCELERATION}. Pick one of auto, none, SSE, Fortran, BlueGene, Power6, ia64, altivec")
endif(${GMX_ACCELERATION} STREQUAL "NONE")
+if(GMX_FORTRAN OR GMX_POWER6)
+ if (GMX_THREADS)
+ message(FATAL_ERROR "FORTRAN/POWER6 is incompatible with threads and only provides a speed-up on certain IBM compilers. Disable FORTRAN (or threads if you really want to use FORTRAN kernels).")
+ endif(GMX_THREADS)
+ enable_language(Fortran)
+ include(FortranCInterface)
+ discover_fortran_mangling(prefix isupper suffix extra_under_score found)
+ if(extra_under_score)
+ set(extrasuffix "_")
+ endif(extra_under_score)
+ if(prefix)
+ set(prefix "${prefix} ##")
+ endif(prefix)
-
-
-
-
+ if(isupper)
+ set(F77_FUNCDEF "${prefix} NAME ## ${suffix}")
+ set(F77_FUNCDEF_ "${prefix} NAME ## ${suffix}${extrasuffix}")
+ else(isupper)
+ set(F77_FUNCDEF "${prefix} name ## ${suffix}")
+ set(F77_FUNCDEF_ "${prefix} name ## ${suffix}${extrasuffix}")
+ endif(isupper)
+else(GMX_FORTRAN OR GMX_POWER6)
+ set(F77_FUNCDEF "name ## _")
+ set(F77_FUNCDEF_ "name ## _")
+endif(GMX_FORTRAN OR GMX_POWER6)
# Process QM/MM Settings
string(TOUPPER ${GMX_QMMM_PROGRAM} ${GMX_QMMM_PROGRAM})
########################################################################
# Specify install locations and which subdirectories to process #
########################################################################
-set(LIB_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/lib)
+if ( DEFINED LIB )
+ set(LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/${LIB}")
+else()
+ set(LIB_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/lib)
+endif()
set(BIN_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/bin)
set(DATA_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/share/gromacs)
set(MAN_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/share/man)
install-exec-hook:
+if NO_LA_FILES
+ cd $(DESTDIR)$(libdir) && rm -f libmd@LIBSUFFIX@.la libgmx@LIBSUFFIX@.la libgmxpreprocess@LIBSUFFIX@.la libgmxana@LIBSUFFIX@.la
+endif
@echo ""
@echo "GROMACS is installed under $(prefix)."
@echo "Make sure to update your PATH and MANPATH to find the"
(cd $(top_builddir)/src/mdlib && $(MAKE) install ; exit 0)
(cd $(top_builddir)/src/kernel && $(MAKE) install-libLTLIBRARIES ; exit 0)
(cd $(top_builddir)/src/kernel && $(MAKE) install-mdrun ; exit 0)
+if NO_LA_FILES
+ cd $(DESTDIR)$(libdir) && rm -f libmd@LIBSUFFIX@.la libgmx@LIBSUFFIX@.la libgmxpreprocess@LIBSUFFIX@.la libgmxana@LIBSUFFIX@.la
+endif
fahcore:
(cd $(top_builddir)/src/gmxlib && $(MAKE) ; exit 0)
Welcome to the official version of GROMACS!
If you are familiar with unix, it should be fairly trivial to compile and
-install GROMACS. Installation instructions are available in the INSTALL file,
-and a more extended step-by-step guide can be found on http://www.gromacs.org .
+install GROMACS. Installation instructions are available in the INSTALL.*
+files (there is one for automake users, INSTALL.automake and one for cmake
+users, INSTALL.cmake). A more extended step-by-step guide can be found
+on our website http://www.gromacs.org .
Of course we will do our utmost to help you with any problems, but PLEASE
READ THE INSTALLATION INSTRUCTIONS BEFORE CONTACTING US!
CPPFLAGS="$save_CPPFLAGS"
LDFLAGS="$save_LDFLAGS"
LIBS="$save_LIBS"
+ DLOPEN_LIBS="$lt_cv_dlopen_libs"
;;
esac
# always use CC for linking:
AC_SUBST(F77LINK,"\$(LINK)")
+#On some systems GNU libtool's la files are more confusing for libtool than helpful due to the
+#hard coded paths/libs in the files. And for better linking we have pkg-config files (.pc).
+AC_ARG_ENABLE(la-files,
+ [AS_HELP_STRING([--disable-la-files],[Do NOT install GNU libtool's la files])],,
+ [enable_la_files=yes])
+AM_CONDITIONAL(NO_LA_FILES,[test "$enable_la_files" = no])
if test "$with_fft" = "fftw2"; then
AC_MSG_ERROR([fftw2 can't be used with threads. Use fftw3 or mkl.])
fi
+ if test "$enable_fortran" = "yes"; then
+ AC_MSG_ERROR([FORTRAN is incompatible with threads and only provides a speed-up on certain IBM compilers. Use --disable-threads if you really want to use FORTRAN kernels.])
+ fi
AC_CHECK_HEADERS(unistd.h)
AC_CHECK_HEADERS(sys/time.h)
AC_CHECK_HEADERS(sched.h)
AC_PROG_LN_S
AC_PROG_MAKE_SET
AC_LIBTOOL_WIN32_DLL
+AC_LIBTOOL_DLOPEN
AC_PROG_LIBTOOL
AC_SYS_LARGEFILE
#
CFLAGS_RET=$CFLAGS
#LDFLAGS="$lt_cv_dlopen_libs $LDFLAGS" #can't make the macro, which is getting lt_cv_dlopen_libs, to work
LDFLAGS_RET=$LDFLAGS
+ LIBS_RET=$LIBS
if test "$enable_all_static" = "yes"; then #make sure we test also whether it works static
LDFLAGS="$LDFLAGS -static"
fi
CFLAGS="-I$srcdir/include -DGMX_DLOPEN $CFLAGS"
- AC_TRY_LINK([#include "$srcdir/src/gmxlib/vmddlopen.c"],,[AC_MSG_RESULT([yes])\
- AC_DEFINE(GMX_DLOPEN,,[Compile with dlopen])],AC_MSG_RESULT([no]))
+ LIBS="$DLOPEN_LIBS $LIBS"
+ AC_TRY_LINK([#include "$srcdir/src/gmxlib/vmddlopen.c"],,[
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(GMX_DLOPEN,,[Compile with dlopen])
+ AC_SUBST(DLOPEN_LIBS)
+ ],[
+ AC_MSG_RESULT([no])
+ AC_SUBST(DLOPEN_LIBS,"")
+ ])
CFLAGS=$CFLAGS_RET
+ LIBS=$LIBS_RET
LDFLAGS=$LDFLAGS_RET
fi
"Written by Emile Apol, Rossen Apostolov, Herman J.C. Berendsen,",
"Aldert van Buuren, Pär Bjelkmar, Rudi van Drunen, Anton Feenstra, ",
"Gerrit Groenhof, Peter Kasson, Per Larsson, Pieter Meulenhoff, ",
- "Teemu Murtola, Szilard Pall, Sander Pronk, Roland Schultz, ",
+ "Teemu Murtola, Szilard Pall, Sander Pronk, Roland Schulz, ",
"Michael Shirts, Alfons Sijbers, Peter Tieleman,\n",
"Berk Hess, David van der Spoel, and Erik Lindahl.\n",
"Copyright (c) 1991-2000, University of Groningen, The Netherlands.",
t_dlist *mk_dlist(FILE *log,
t_atoms *atoms, int *nlist,
gmx_bool bPhi, gmx_bool bPsi, gmx_bool bChi, gmx_bool bHChi,
- int maxchi,int r0,int naa,char **aa);
+ int maxchi, int r0, gmx_residuetype_t rt);
void pr_dlist(FILE *fp,int nl,t_dlist dl[],real dt, int printtype,
gmx_bool bPhi, gmx_bool bPsi,gmx_bool bChi,gmx_bool bOmega, int maxchi);
gmx_bool
gmx_residuetype_is_rna(gmx_residuetype_t rt, const char *resnm);
+int
+gmx_residuetype_get_size(gmx_residuetype_t rt);
+
+int
+gmx_residuetype_get_index(gmx_residuetype_t rt, const char *resnm);
+
+const char *
+gmx_residuetype_get_name(gmx_residuetype_t rt, int index);
+
#include "vsite.h"
#include "pull.h"
#include "update.h"
-#include "gmx_membed.h"
+#include "membed.h"
#ifdef __cplusplus
extern "C" {
#define GMX_PME_SOLVE (1<<1)
#define GMX_PME_CALC_F (1<<2)
#define GMX_PME_CALC_ENER_VIR (1<<3)
+/* This forces the grid to be backtransformed even without GMX_PME_CALC_F */
+#define GMX_PME_CALC_POT (1<<4)
#define GMX_PME_DO_ALL_F (GMX_PME_SPREAD_Q | GMX_PME_SOLVE | GMX_PME_CALC_F)
int gmx_pme_do(gmx_pme_t pme,
tmppath=""
for i in `echo $LD_LIBRARY_PATH | sed "s/:/ /g"`; do
if test "$i" != "$GMXLDLIB"; then
+ if test "${tmppath}" == ""; then
+ tmppath=$i
+ else
tmppath=${tmppath}:$i
fi
+ fi
done
LD_LIBRARY_PATH=$tmppath
tmppath=${tmppath}:$i
fi
done
+if test "$tmppath" == ""; then
+ tmppath=":"
+fi
MANPATH=$tmppath
##########################################################
tmppath=""
for i in `echo $LD_LIBRARY_PATH | sed "s/:/ /g"`; do
if test "$i" != "$GMXLDLIB"; then
+ if test "${tmppath}" == ""; then
+ tmppath=$i
+ else
tmppath=${tmppath}:$i
fi
+ fi
done
LD_LIBRARY_PATH=$tmppath
tmppath=${tmppath}:$i
fi
done
+if test "$tmppath" == ""; then
+ tmppath=":"
+fi
MANPATH=$tmppath
##########################################################
# remove previous gromacs part from ld_library_path
set tmppath = ""
foreach i ( `echo $LD_LIBRARY_PATH | sed "s/:/ /g"` )
- if ( "$i" != "$GMXLDLIB" ) set tmppath = "${tmppath}:$i"
+ if ( "$i" != "$GMXLDLIB" ) then
+ if ("${tmppath}" == "") then
+ set tmppath = "$i"
+ else
+ set tmppath = "${tmppath}:$i"
+ endif
+ endif
end
setenv LD_LIBRARY_PATH $tmppath
foreach i ( `echo $MANPATH | sed "s/:/ /g"` )
if ( "$i" != "$GMXMAN" ) set tmppath = "${tmppath}:$i"
end
+if ("$tmppath" == "") then
+ set tmppath = ":"
+endif
setenv MANPATH $tmppath
##########################################################
# remove previous gromacs part from ld_library_path
set tmppath = ""
foreach i ( `echo $LD_LIBRARY_PATH | sed "s/:/ /g"` )
- if ( "$i" != "$GMXLDLIB" ) set tmppath = "${tmppath}:$i"
+ if ( "$i" != "$GMXLDLIB" ) then
+ if ("${tmppath}" == "") then
+ set tmppath = "$i"
+ else
+ set tmppath = "${tmppath}:$i"
+ endif
+ endif
end
setenv LD_LIBRARY_PATH $tmppath
foreach i ( `echo $MANPATH | sed "s/:/ /g"` )
if ( "$i" != "$GMXMAN" ) set tmppath = "${tmppath}:$i"
end
+if ("$tmppath" == "") then
+ set tmppath = ":"
+endif
setenv MANPATH $tmppath
##########################################################
tmppath=""
for i in `echo $LD_LIBRARY_PATH | sed "s/:/ /g"`; do
if test "$i" != "$GMXLDLIB"; then
+ if test "${tmppath}" = ""; then
+ tmppath=$i
+ else
tmppath=${tmppath}:$i
fi
+ fi
done
LD_LIBRARY_PATH=$tmppath
tmppath=${tmppath}:$i
fi
done
+if test "$tmppath" = ""; then
+ tmppath=":"
+fi
MANPATH=$tmppath
##########################################################
tmppath=""
for i in `echo $LD_LIBRARY_PATH | sed "s/:/ /g"`; do
if test "$i" != "$GMXLDLIB"; then
+ if test "${tmppath}" = ""; then
+ tmppath=$i
+ else
tmppath=${tmppath}:$i
fi
+ fi
done
LD_LIBRARY_PATH=$tmppath
tmppath=${tmppath}:$i
fi
done
+if test "$tmppath" = ""; then
+ tmppath=":"
+fi
MANPATH=$tmppath
##########################################################
nstpcouple, tau_p, compressibility, ref_p, refcoord_scaling)
<li><A HREF="#sa"><b>simulated annealing</b></A> (annealing, annealing_npoints, annealing_time, annealing_temp)
<li><A HREF="#vel"><b>velocity generation</b></A> (gen_vel, gen_temp, gen_seed)
-<li><A HREF="#bond"><b>bonds</b></A> (constraints, constraint_algorithm, unconstrained_start, shake_tol, lincs_order, lincs_iter, lincs_warnangle, morse)
+<li><A HREF="#bond"><b>bonds</b></A> (constraints, constraint_algorithm, continuation, shake_tol, lincs_order, lincs_iter, lincs_warnangle, morse)
<li><A HREF="#egexcl"><b>Energy group exclusions</b></A> (energygrp_excl)
<li><A HREF="#walls"><b>Walls</b></A> (nwall, wall_type, wall_r_linpot, wall_atomtype,
wall_density, wall_ewald_zfac)
SHAKE can not be used with energy minimization.
</dd>
</dl></dd>
-<dt><b>unconstrained_start:</b></dt>
+<dt><b>continuation:</b></dt>
+<dd>This option was formerly known as <tt>unconstrained_start</tt>.</dd>
<dd><dl compact>
<dt><b>no</b></dt>
<dd>apply constraints to the start configuration and reset shells</dd>
<dt></dt><b>sa_algorithm</b>
<dd><dl compact="compact">
-<dt><b>Ace-approx</b></dt>
+<dt><b>Ace-approximation</b></dt>
<dd>Use an Ace-type approximation (default)</dd>
<dt><b>None</b></dt>
<dd>No non-polar solvation calculation done. For GBSA only the polar part gets
<A HREF="#tc">tc_grps</A><br>
<A HREF="#tc">tcoupl</A><br>
<A HREF="#run">tinit</A><br>
-<A HREF="#bond">unconstrained_start</A><br>
+<A HREF="#bond">continuation</A><br>
<A HREF="#user">user1_grps</A><br>
<A HREF="#user">user2_grps</A><br>
<A HREF="#user">userint1</A><br>
CLEANFILES = Makefile.@host@ Makefile.@host@_double *~ \\\#*
template_SOURCES = template.c
-#noinst_PROGRAMS = template
+noinst_PROGRAMS = template
LDADD = ../../src/mdlib/libmd@LIBSUFFIX@.la ../../src/gmxlib/libgmx@LIBSUFFIX@.la
#template.$(OBJEXT): gromacs
aminoacids.n.tdb dna.rtp forcefield.itp spc.itp \
aminoacids.r2b ffbonded.itp gb.itp tip3p.itp \
aminoacids.rtp ffnabonded.itp ions.itp tip4p.itp \
-spce.itp tips3p.itp watermodels.dat tip5p.itp
+spce.itp tips3p.itp watermodels.dat tip5p.itp \
+dna.hdb dna.n.tdb dna.c.tdb dna.arn \
+rna.hdb rna.n.tdb rna.c.tdb rna.arn \
+rna.r2b
EXTRA_DIST = ${topol_DATA}
--- /dev/null
+DNA C7 C5M
+DNA H71 H51
+DNA H72 H52
+DNA H73 H53
+DNA OP1 O1P
+DNA OP2 O2P
+DNA H2' H2'1
+DNA H2'' H2'2
+DNA H5' H5'1
+DNA H5'' H5'2
+DNA HO5' H5T
+DNA HO3' H3T
--- /dev/null
+[ None ]
+
+[ 3' ]
+[ replace ]
+C3' C3' CN7 12.011 0.14
+H3' H3' HN7 1.008 0.09
+O3' O3' ON5 15.9994 -0.66
+[ Add ]
+1 2 H3T O3' C3' C4'
+ HN5 1.008 0.43
--- /dev/null
+DA 8
+2 6 H5' C5' O5' C4'
+1 5 H4' C4' C5' O4' C3'
+1 5 H1' C1' O4' N9 C2'
+1 1 H8 C8 N9 N7
+2 3 H6 N6 C6 C5
+1 1 H2 C2 N1 N3
+1 5 H3' C3' C4' C2' O3'
+2 6 H2' C2' C1' C3'
+DT 8
+2 6 H5' C5' O5' C4'
+1 5 H4' C4' C5' O4' C3'
+1 5 H1' C1' O4' N1 C2'
+1 1 H6 C6 N1 C5
+3 4 H5 C5M C5 C6
+1 1 H3 N3 C4 C2
+1 5 H3' C3' C4' C2' O3'
+2 6 H2' C2' C1' C3'
+DG 8
+2 6 H5' C5' O5' C4'
+1 5 H4' C4' C5' O4' C3'
+1 5 H1' C1' O4' N9 C2'
+1 1 H8 C8 N9 N7
+1 1 H1 N1 C6 C2
+2 3 H2 N2 C2 N1
+1 5 H3' C3' C4' C2' O3'
+2 6 H2' C2' C1' C3'
+DC 8
+2 6 H5' C5' O5' C4'
+1 5 H4' C4' C5' O4' C3'
+1 5 H1' C1' O4' N1 C2'
+1 1 H6 C6 N1 C5
+1 1 H5 C5 C6 C4
+2 3 H4 N4 C4 C5
+1 5 H3' C3' C4' C2' O3'
+2 6 H2' C2' C1' C3'
--- /dev/null
+[ None ]
+
+[ 5' ]
+[ delete ]
+ P
+ O1P
+ O2P
+[ replace ]
+O5' O5' ON5 15.9994 -0.66
+C5' C5' CN8B 12.011 0.05
+[ Add ]
+ 1 2 H5T O5' C5' C4'
+ HN5 1.008 0.43
+
+
+
+++ /dev/null
-; rtp residue to rtp building block table
-;GMX Force-field
-DA DA DA5 DA3 -
-DG DG DG5 DG3 -
-DC DC DC5 DC3 -
-DT DT DT5 DT3 -
-
N6 C6 H61 H62
C6 N1 C5 N6
-[ DA5 ]
-; H61 H62;
-; \ /
-; N6
-; |
-; C6
-; // \
-; N1 C5--N7\\
-; | || C8-H8
-; C2 C4--N9/
-; / \\ / \
-; H2 N3 \
-; \
-; \
-; \
-; H5'1H4' O4' \
-; | \ / \ \
-; H5T-O5'-C5'---C4' C1'
-; | \ / \
-; H5'2 C3'--C2' H1'
-; / \ / \
-; O3' H3' H2'1 H2'2
-; |
-;
-;
-[ atoms ]
-H5T HN5 0.43 0
-O5' ON5 -0.66 1
-C5' CN8B 0.05 2
-H5'1 HN8 0.09 3
-H5'2 HN8 0.09 4
-C4' CN7 0.16 5
-H4' HN7 0.09 6
-O4' ON6 -0.50 7
-C1' CN7B 0.16 8
-H1' HN7 0.09 9
-N9 NN2 -0.05 10
-C5 CN5 0.28 11
-N7 NN4 -0.71 12
-C8 CN4 0.34 13
-H8 HN3 0.12 14
-N1 NN3A -0.74 15
-C2 CN4 0.50 16
-H2 HN3 0.13 17
-N3 NN3A -0.75 18
-C4 CN5 0.43 19
-C6 CN2 0.46 20
-N6 NN1 -0.77 21
-H61 HN1 0.38 22
-H62 HN1 0.38 23
-C2' CN8 -0.18 24
-H2'1 HN8 0.09 25
-H2'2 HN8 0.09 26
-C3' CN7 0.01 27
-H3' HN7 0.09 28
-O3' ON2 -0.57 29
-[ bonds ]
-H5T O5'
-O5' C5'
-C5' C4'
-C4' O4'
-C4' C3'
-O4' C1'
-C1' N9
-C1' C2'
-N9 C4
-N9 C8
-C4 N3
-C2 N1
-C6 N6
-N6 H61
-N6 H62
-C6 C5
-C5 N7
-C2' C3'
-C3' O3'
-C1' H1'
-C2' H2'1
-C2' H2'2
-C3' H3'
-C4' H4'
-C5' H5'1
-C5' H5'2
-C8 H8
-C2 H2
-N1 C6
-C2 N3
-C4 C5
-N7 C8
-[ impropers ]
-N6 C6 H61 H62
-C6 N1 C5 N6
-
-
-[ DA3 ]
-; H61 H62;
-; \ /
-; N6
-; |
-; C6
-; // \
-; N1 C5--N7\\
-; | || C8-H8
-; C2 C4--N9/
-; / \\ / \
-; H2 N3 \
-; \
-; \
-; \
-; O1P H5'1 H4' O4' \
-; | | \ / \ \
-; -P-O5'-C5'---C4' C1'
-; | | \ / \
-; O2P H5'2 C3'--C2' H1'
-; / \ / \
-; O3' H3' H2'1 H2'2
-; |
-; H3T
-
-[ atoms ]
-P P 1.50 0
-O1P ON3 -0.78 1
-O2P ON3 -0.78 2
-O5' ON2 -0.57 3
-C5' CN8B -0.08 4
-H5'1 HN8 0.09 5
-H5'2 HN8 0.09 6
-C4' CN7 0.16 7
-H4' HN7 0.09 8
-O4' ON6 -0.50 9
-C1' CN7B 0.16 10
-H1' HN7 0.09 11
-N9 NN2 -0.05 12
-C5 CN5 0.28 13
-N7 NN4 -0.71 14
-C8 CN4 0.34 15
-H8 HN3 0.12 16
-N1 NN3A -0.74 17
-C2 CN4 0.50 18
-H2 HN3 0.13 19
-N3 NN3A -0.75 20
-C4 CN5 0.43 21
-C6 CN2 0.46 22
-N6 NN1 -0.77 23
-H61 HN1 0.38 24
-H62 HN1 0.38 25
-C2' CN8 -0.18 26
-H2'1 HN8 0.09 27
-H2'2 HN8 0.09 28
-C3' CN7 0.14 29
-H3' HN7 0.09 30
-O3' ON5 -0.66 31
-H3T HN5 0.43 32
-[ bonds ]
--O3' P
-P O1P
-P O2P
-P O5'
-O5' C5'
-C5' C4'
-C4' O4'
-C4' C3'
-O4' C1'
-C1' N9
-C1' C2'
-N9 C4
-N9 C8
-C4 N3
-C2 N1
-C6 N6
-N6 H61
-N6 H62
-C6 C5
-C5 N7
-C2' C3'
-C3' O3'
-O3' H3T
-C1' H1'
-C2' H2'1
-C2' H2'2
-C3' H3'
-C4' H4'
-C5' H5'1
-C5' H5'2
-C8 H8
-C2 H2
-N1 C6
-C2 N3
-C4 C5
-N7 C8
-[ impropers ]
-N6 C6 H61 H62
-C6 N1 C5 N6
-
;--------------------------------------------------------------------------
[ DC ]
;
C2 CN1 0.52 17
O2 ON1C -0.49 18
N3 NN3 -0.66 19
-C4 CN2 0.65 20
-N4 NN1 -0.75 21
-H41 HN1 0.37 22
-H42 HN1 0.33 23
-C2' CN8 -0.18 24
-H2'1 HN8 0.09 25
-H2'2 HN8 0.09 26
-C3' CN7 0.01 27
-H3' HN7 0.09 28
-O3' ON2 -0.57 29
-[ bonds ]
--O3' P
-P O1P
-P O2P
-P O5'
-O5' C5'
-C5' C4'
-C4' O4'
-C4' C3'
-O4' C1'
-C1' N1
-C1' C2'
-N1 C2
-N1 C6
-C2 N3
-C4 N4
-N4 H41
-N4 H42
-C4 C5
-C2' C3'
-C3' O3'
-C1' H1'
-C2' H2'1
-C2' H2'2
-C3' H3'
-C4' H4'
-C5' H5'1
-C5' H5'2
-C5 H5
-C6 H6
-C2 O2
-C5 C6
-N3 C4
-[ impropers ]
-C2 N1 N3 O2
-C4 N3 C5 N4
-N4 C4 H41 H42
-
-[ DC5 ]
-;
-; H42 H41
-; \ /
-; N4
-; |
-; C4
-; / \\
-; H5-C5 N3
-; || |
-; H6-C6 C2
-; \ / \\
-; N1 O2
-; \
-; \
-; \
-; H5'1H4' O4' \
-; | \ / \ \
-; H5T-O5'-C5'---C4' C1'
-; | \ / \
-; H5'2 C3'--C2' H1'
-; / \ / \
-; O3' H3' H2'1 H2'2
-; |
-;
-[ atoms ]
-H5T HN5 0.43 0
-O5' ON5 -0.66 1
-C5' CN8B 0.05 2
-H5'1 HN8 0.09 3
-H5'2 HN8 0.09 4
-C4' CN7 0.16 5
-H4' HN7 0.09 6
-O4' ON6 -0.50 7
-C1' CN7B 0.16 8
-H1' HN7 0.09 9
-N1 NN2 -0.13 10
-C6 CN3 0.05 11
-H6 HN3 0.17 12
-C5 CN3 -0.13 13
-H5 HN3 0.07 14
-C2 CN1 0.52 15
-O2 ON1C -0.49 16
-N3 NN3 -0.66 17
-C4 CN2 0.65 18
-N4 NN1 -0.75 19
-H41 HN1 0.37 20
-H42 HN1 0.33 21
-C2' CN8 -0.18 22
-H2'1 HN8 0.09 23
-H2'2 HN8 0.09 24
-C3' CN7 0.01 25
-H3' HN7 0.09 26
-O3' ON2 -0.57 27
-[ bonds ]
-H5T O5'
-O5' C5'
-C5' C4'
-C4' O4'
-C4' C3'
-O4' C1'
-C1' N1
-C1' C2'
-N1 C2
-N1 C6
-C2 N3
-C4 N4
-N4 H41
-N4 H42
-C4 C5
-C2' C3'
-C3' O3'
-C1' H1'
-C2' H2'1
-C2' H2'2
-C3' H3'
-C4' H4'
-C5' H5'1
-C5' H5'2
-C5 H5
-C6 H6
-C2 O2
-C5 C6
-N3 C4
-[ impropers ]
-C2 N1 N3 O2
-C4 N3 C5 N4
-N4 C4 H41 H42
-
-[ DC3 ]
-;
-; H42 H41
-; \ /
-; N4
-; |
-; C4
-; / \\
-; H5-C5 N3
-; || |
-; H6-C6 C2
-; \ / \\
-; N1 O2
-; \
-; \
-; \
-; O1P H5'1H4' O4' \
-; | | \ / \ \
-; -P-O5'-C5'---C4' C1'
-; | | \ / \
-; O2P H5'2 C3'--C2' H1'
-; / \ / \
-; O3' H3' H2'1 H2'2
-; |
-; H3T
-[ atoms ]
-P P 1.50 0
-O1P ON3 -0.78 1
-O2P ON3 -0.78 2
-O5' ON2 -0.57 3
-C5' CN8B -0.08 4
-H5'1 HN8 0.09 5
-H5'2 HN8 0.09 6
-C4' CN7 0.16 7
-H4' HN7 0.09 8
-O4' ON6 -0.50 9
-C1' CN7B 0.16 10
-H1' HN7 0.09 11
-N1 NN2 -0.13 12
-C6 CN3 0.05 13
-H6 HN3 0.17 14
-C5 CN3 -0.13 15
-H5 HN3 0.07 16
-C2 CN1 0.52 17
-O2 ON1C -0.49 18
-N3 NN3 -0.66 19
-C4 CN2 0.65 20
-N4 NN1 -0.75 21
-H41 HN1 0.37 22
-H42 HN1 0.33 23
-C2' CN8 -0.18 24
-H2'1 HN8 0.09 25
-H2'2 HN8 0.09 26
-C3' CN7 0.14 27
-H3' HN7 0.09 28
-O3' ON5 -0.66 29
-H3T HN5 0.43 30
-[ bonds ]
--O3' P
-P O1P
-P O2P
-P O5'
-O5' C5'
-C5' C4'
-C4' O4'
-C4' C3'
-O4' C1'
-C1' N1
-C1' C2'
-N1 C2
-N1 C6
-C2 N3
-C4 N4
-N4 H41
-N4 H42
-C4 C5
-C2' C3'
-C3' O3'
-O3' H3T
-C1' H1'
-C2' H2'1
-C2' H2'2
-C3' H3'
-C4' H4'
-C5' H5'1
-C5' H5'2
-C5 H5
-C6 H6
-C2 O2
-C5 C6
-N3 C4
-[ impropers ]
-C2 N1 N3 O2
-C4 N3 C5 N4
-N4 C4 H41 H42
-
-; --------------------------------------------------------------------
-[ DG ]
-; O6
-; ||
-; C6
-; / \
-; H1-N1 C5--N7\\
-; | || C8-H8
-; C2 C4--N9/
-; / \\ / \
-; H21-N2 N3 \
-; | \
-; H22 \
-; \
-; O1P H5'1 H4' O4' \
-; | | \ / \ \
-; -P-O5'-C5'---C4' C1'
-; | | \ / \
-; O2P H5'2 C3'--C2' H1'
-; / \ / \
-; O3' H3' H2'1 H2'2
-; |
-;
-[ atoms ]
-P P 1.50 0
-O1P ON3 -0.78 1
-O2P ON3 -0.78 2
-O5' ON2 -0.57 3
-C5' CN8B -0.08 4
-H5'1 HN8 0.09 5
-H5'2 HN8 0.09 6
-C4' CN7 0.16 7
-H4' HN7 0.09 8
-O4' ON6 -0.50 9
-C1' CN7B 0.16 10
-H1' HN7 0.09 11
-N9 NN2B -0.02 12
-C4 CN5 0.26 13
-N2 NN1 -0.68 14
-H21 HN1 0.32 15
-H22 HN1 0.35 16
-N3 NN3G -0.74 17
-C2 CN2 0.75 18
-N1 NN2G -0.34 19
-H1 HN2 0.26 20
-C6 CN1 0.54 21
-O6 ON1 -0.51 22
-C5 CN5G 0.00 23
-N7 NN4 -0.60 24
-C8 CN4 0.25 25
-H8 HN3 0.16 26
-C2' CN8 -0.18 27
-H2'1 HN8 0.09 28
-H2'2 HN8 0.09 29
-C3' CN7 0.01 30
-H3' HN7 0.09 31
-O3' ON2 -0.57 32
+C4 CN2 0.65 20
+N4 NN1 -0.75 21
+H41 HN1 0.37 22
+H42 HN1 0.33 23
+C2' CN8 -0.18 24
+H2'1 HN8 0.09 25
+H2'2 HN8 0.09 26
+C3' CN7 0.01 27
+H3' HN7 0.09 28
+O3' ON2 -0.57 29
[ bonds ]
-O3' P
P O1P
C4' O4'
C4' C3'
O4' C1'
-C1' N9
+C1' N1
C1' C2'
-N9 C4
-N9 C8
-C4 N3
-C2 N2
-C2 N1
-N2 H21
-N2 H22
-N1 H1
+N1 C2
N1 C6
-C6 C5
-C5 N7
-C2' C3'
-C3' O3'
-C1' H1'
-C2' H2'1
-C2' H2'2
-C3' H3'
-C4' H4'
-C5' H5'1
-C5' H5'2
-C8 H8
C2 N3
+C4 N4
+N4 H41
+N4 H42
C4 C5
-N7 C8
-C6 O6
-[ impropers ]
-C2 N3 N1 N2
-C6 N1 C5 O6
-N2 H21 C2 H22
-
-[ DG5 ]
-; O6
-; ||
-; C6
-; / \
-; H1-N1 C5--N7\\
-; | || C8-H8
-; C2 C4--N9/
-; / \\ / \
-; H21-N2 N3 \
-; | \
-; H22 \
-; \
-; H5'1H4' O4' \
-; | \ / \ \
-; H5T-O5'-C5'---C4' C1'
-; | \ / \
-; H5'2 C3'--C2' H1'
-; / \ / \
-; O3' H3' H2'1 H2'2
-; |
-;
-[ atoms ]
-H5T HN5 0.43 0
-O5' ON5 -0.66 1
-C5' CN8B 0.05 2
-H5'1 HN8 0.09 3
-H5'2 HN8 0.09 4
-C4' CN7 0.16 5
-H4' HN7 0.09 6
-O4' ON6 -0.50 7
-C1' CN7B 0.16 8
-H1' HN7 0.09 9
-N9 NN2B -0.02 10
-C4 CN5 0.26 11
-N2 NN1 -0.68 12
-H21 HN1 0.32 13
-H22 HN1 0.35 14
-N3 NN3G -0.74 15
-C2 CN2 0.75 16
-N1 NN2G -0.34 17
-H1 HN2 0.26 18
-C6 CN1 0.54 19
-O6 ON1 -0.51 20
-C5 CN5G 0.00 21
-N7 NN4 -0.60 22
-C8 CN4 0.25 23
-H8 HN3 0.16 24
-C2' CN8 -0.18 25
-H2'1 HN8 0.09 26
-H2'2 HN8 0.09 27
-C3' CN7 0.01 28
-H3' HN7 0.09 29
-O3' ON2 -0.57 30
-[ bonds ]
-H5T O5'
-O5' C5'
-C5' C4'
-C4' O4'
-C4' C3'
-O4' C1'
-C1' N9
-C1' C2'
-N9 C4
-N9 C8
-C4 N3
-C2 N2
-C2 N1
-N2 H21
-N2 H22
-N1 H1
-N1 C6
-C6 C5
-C5 N7
C2' C3'
C3' O3'
C1' H1'
C4' H4'
C5' H5'1
C5' H5'2
-C8 H8
-C2 N3
-C4 C5
-N7 C8
-C6 O6
+C5 H5
+C6 H6
+C2 O2
+C5 C6
+N3 C4
[ impropers ]
-C2 N3 N1 N2
-C6 N1 C5 O6
-N2 H21 C2 H22
-
-[ DG3 ]
+C2 N1 N3 O2
+C4 N3 C5 N4
+N4 C4 H41 H42
+
+; --------------------------------------------------------------------
+[ DG ]
; O6
; ||
; C6
; | | \ / \
; O2P H5'2 C3'--C2' H1'
; / \ / \
-; O3' H3' H2'1 H2'2
-; |
-; H3T
+; O3' H3' H2'1 H2'2
+; |
+;
[ atoms ]
P P 1.50 0
O1P ON3 -0.78 1
C2' CN8 -0.18 27
H2'1 HN8 0.09 28
H2'2 HN8 0.09 29
-C3' CN7 0.14 30
+C3' CN7 0.01 30
H3' HN7 0.09 31
-O3' ON5 -0.66 32
-H3T HN5 0.43 33
+O3' ON2 -0.57 32
[ bonds ]
-O3' P
P O1P
C5 N7
C2' C3'
C3' O3'
-O3' H3T
C1' H1'
C2' H2'1
C2' H2'2
C4 N3 C5 O4
C5 C4 C6 C5M
-[ DT5 ]
-; H51 O4
-; | ||
-; H52-C5M C4 H3
-; | \ / \ /
-; H53 C5 N3
-; || |
-; H6-C6 C2
-; \ / \\
-; N1 O2
-; \
-; \
-; \
-; H5'1H4' O4' \
-; | \ / \ \
-; H5T-O5'-C5'---C4' C1'
-; | \ / \
-; H5'2 C3'--C2' H1'
-; / \ / \
-; O3' H3' H2'1 H2'2
-; |
-;
-;
-[ atoms ]
-H5T HN5 0.43 0
-O5' ON5 -0.66 1
-C5' CN8B 0.05 2
-H5'1 HN8 0.09 3
-H5'2 HN8 0.09 4
-C4' CN7 0.16 5
-H4' HN7 0.09 6
-O4' ON6 -0.50 7
-C1' CN7B 0.16 8
-H1' HN7 0.09 9
-N1 NN2B -0.34 10
-C6 CN3 0.17 11
-H6 HN3 0.17 12
-C2 CN1T 0.51 13
-O2 ON1 -0.41 14
-N3 NN2U -0.46 15
-H3 HN2 0.36 16
-C4 CN1 0.50 17
-O4 ON1 -0.45 18
-C5 CN3T -0.15 19
-C5M CN9 -0.11 20
-H51 HN9 0.07 21
-H52 HN9 0.07 22
-H53 HN9 0.07 23
-C2' CN8 -0.18 24
-H2'1 HN8 0.09 25
-H2'2 HN8 0.09 26
-C3' CN7 0.01 27
-H3' HN7 0.09 28
-O3' ON2 -0.57 29
-[ bonds ]
-H5T O5'
-O5' C5'
-C5' C4'
-C4' O4'
-C4' C3'
-O4' C1'
-C1' N1
-C1' C2'
-N1 C2
-N1 C6
-C2 N3
-N3 H3
-N3 C4
-C4 C5
-C5 C5M
-C2' C3'
-C3' O3'
-C1' H1'
-C2' H2'1
-C2' H2'2
-C3' H3'
-C4' H4'
-C5' H5'1
-C5' H5'2
-C6 H6
-C5M H51
-C5M H52
-C5M H53
-C2 O2
-C4 O4
-C5 C6
-[ impropers ]
-C2 N1 N3 O2
-C4 N3 C5 O4
-C5 C4 C6 C5M
-
-[ DT3 ]
-; H51 O4
-; | ||
-; H52-C5M C4 H3
-; | \ / \ /
-; H53 C5 N3
-; || |
-; H6-C6 C2
-; \ / \\
-; N1 O2
-; \
-; \
-; \
-; O1P H5'1H4' O4' \
-; | | \ / \ \
-; -P-O5'-C5'---C4' C1'
-; | | \ / \
-; O2P H5'2 C3'--C2' H1'
-; / \ / \
-; O3' H3' H2'1 H2'2
-; |
-; H3T
-;
-[ atoms ]
-P P 1.50 0
-O1P ON3 -0.78 1
-O2P ON3 -0.78 2
-O5' ON2 -0.57 3
-C5' CN8B -0.08 4
-H5'1 HN8 0.09 5
-H5'2 HN8 0.09 6
-C4' CN7 0.16 7
-H4' HN7 0.09 8
-O4' ON6 -0.50 9
-C1' CN7B 0.16 10
-H1' HN7 0.09 11
-N1 NN2B -0.34 12
-C6 CN3 0.17 13
-H6 HN3 0.17 14
-C2 CN1T 0.51 15
-O2 ON1 -0.41 16
-N3 NN2U -0.46 17
-H3 HN2 0.36 18
-C4 CN1 0.50 19
-O4 ON1 -0.45 20
-C5 CN3T -0.15 21
-C5M CN9 -0.11 22
-H51 HN9 0.07 23
-H52 HN9 0.07 24
-H53 HN9 0.07 25
-C2' CN8 -0.18 26
-H2'1 HN8 0.09 27
-H2'2 HN8 0.09 28
-C3' CN7 0.14 29
-H3' HN7 0.09 30
-O3' ON5 -0.66 31
-H3T HN5 0.43 32
-[ bonds ]
--O3' P
-P O1P
-P O2P
-P O5'
-O5' C5'
-C5' C4'
-C4' O4'
-C4' C3'
-O4' C1'
-C1' N1
-C1' C2'
-N1 C2
-N1 C6
-C2 N3
-N3 H3
-N3 C4
-C4 C5
-C5 C5M
-C2' C3'
-C3' O3'
-O3' H3T
-C1' H1'
-C2' H2'1
-C2' H2'2
-C3' H3'
-C4' H4'
-C5' H5'1
-C5' H5'2
-C6 H6
-C5M H51
-C5M H52
-C5M H53
-C2 O2
-C4 O4
-C5 C6
-[ impropers ]
-C2 N1 N3 O2
-C4 N3 C5 O4
-C5 C4 C6 C5M
-
MNH3 0 0.000000 0.00 A 0.0 0.0
MNH2 0 0.000000 0.00 A 0.0 0.0
MCH3 0 0.000000 0.00 A 0.0 0.0
+MCH3S 0 0.000000 0.00 A 0.0 0.0
; Ions and noble gases (useful for tutorials)
Cu2+ 29 63.54600 2.00 A 2.08470e-01 4.76976e+00
Ar 18 39.94800 0.00 A 3.41000e-01 2.74580e-02
--- /dev/null
+RNA OP1 O1P
+RNA OP2 O2P
+RNA H2' H2'1
+RNA H2'' H2'2
+RNA H5' H5'1
+RNA H5'' H5'2
+RNA HO5' H5T
+RNA HO3' H3T
--- /dev/null
+[ None ]
+
+[ 3' ]
+[ replace ]
+C3' C3' CN7 12.011 0.14
+H3' H3' HN7 1.008 0.09
+O3' O3' ON5 15.9994 -0.66
+[ Add ]
+1 2 H3T O3' C3' C4'
+ HN5 1.008 0.43
--- /dev/null
+RA 9
+2 6 H5' C5' O5' C4'
+1 5 H4' C4' C5' O4' C3'
+1 5 H1' C1' O4' N9 C2'
+1 1 H8 C8 N9 N7
+2 3 H6 N6 C6 C5
+1 1 H2 C2 N1 N3
+1 5 H3' C3' C4' C2' O3'
+1 5 H2'2 C2' C1' C3' O2'
+1 2 H2'1 O2' C2' C1'
+RU 9
+2 6 H5' C5' O5' C4'
+1 5 H4' C4' C5' O4' C3'
+1 5 H1' C1' O4' N1 C2'
+1 1 H6 C6 N1 C5
+1 1 H5 C5 C6 C4
+1 1 H3 N3 C4 C2
+1 5 H3' C3' C4' C2' O3'
+1 5 H2'2 C2' C1' C3' O2'
+1 2 H2'1 O2' C2' C1'
+RG 9
+2 6 H5' C5' O5' C4'
+1 5 H4' C4' C5' O4' C3'
+1 5 H1' C1' O4' N9 C2'
+1 1 H8 C8 N9 N7
+1 1 H1 N1 C6 C2
+2 3 H2 N2 C2 N1
+1 5 H3' C3' C4' C2' O3'
+1 5 H2'2 C2' C1' C3' O2'
+1 2 H2'1 O2' C2' C1'
+RC 9
+2 6 H5' C5' O5' C4'
+1 5 H4' C4' C5' O4' C3'
+1 5 H1' C1' O4' N1 C2'
+1 1 H6 C6 N1 C5
+1 1 H5 C5 C6 C4
+2 3 H4 N4 C4 C5
+1 5 H3' C3' C4' C2' O3'
+1 5 H2'2 C2' C1' C3' O2'
+1 2 H2'1 O2' C2' C1'
--- /dev/null
+[ None ]
+
+[ 5' ]
+[ delete ]
+ P
+ O1P
+ O2P
+[ replace ]
+O5' O5' ON5 15.9994 -0.66
+C5' C5' CN8B 12.011 0.05
+[ Add ]
+ 1 2 H5T O5' C5' C4'
+ HN5 1.008 0.43
+
+
+
; rtp residue to rtp building block table
;GMX Force-field
-A RA RA5 RA3 RA
-G RG RG5 RG3 RG
-C RC RC5 RC3 RC
-U RU RU5 RU3 RU
+A RA
+G RG
+C RC
+U RU
N6 C6 H61 H62
C6 N1 C5 N6
-[ RA5 ]
- ; H61 H62;
- ; \ /
- ; N6
- ; |
- ; C6
- ; // \
- ; N1 C5--N7\\
- ; | || C8-H8
- ; C2 C4--N9/
- ; / \\ / \
- ; H2 N3 \
- ; \
- ; \
- ; \
- ; H5'1H4' O4' \
- ; | \ / \ \
- ; H5T-O5'-C5'---C4' C1'
- ; | \ / \
- ; H5'2 C3'--C2' H1'
- ; / \ / \
- ; O3' H3' O2' H2'2
- ; | |
- ; H2'1
- ;
-[ atoms ]
-H5T HN5 0.43 0
-O5' ON5 -0.66 1
-C5' CN8B 0.05 2
-H5'1 HN8 0.09 3
-H5'2 HN8 0.09 4
-C4' CN7 0.16 5
-H4' HN7 0.09 6
-O4' ON6B -0.50 7
-C1' CN7B 0.16 8
-H1' HN7 0.09 9
-N9 NN2 -0.05 10
-C5 CN5 0.28 11
-N7 NN4 -0.71 12
-C8 CN4 0.34 13
-H8 HN3 0.12 14
-N1 NN3A -0.74 15
-C2 CN4 0.50 16
-H2 HN3 0.13 17
-N3 NN3A -0.75 18
-C4 CN5 0.43 19
-C6 CN2 0.46 20
-N6 NN1 -0.77 21
-H61 HN1 0.38 22
-H62 HN1 0.38 23
-C2' CN7B 0.14 24
-H2'2 HN7 0.09 25
-O2' ON5 -0.66 26
-H2'1 HN5 0.43 27
-C3' CN7 0.01 28
-H3' HN7 0.09 29
-O3' ON2 -0.57 30
-[ bonds ]
-H5T O5'
-O5' C5'
-C5' C4'
-C4' O4'
-C4' C3'
-O4' C1'
-C1' N9
-C1' C2'
-N9 C4
-N9 C8
-C4 N3
-C2 N1
-C6 N6
-N6 H61
-N6 H62
-C6 C5
-C5 N7
-C2' C3'
-C2' O2'
-O2' H2'1
-C3' O3'
-C1' H1'
-C2' H2'2
-C3' H3'
-C4' H4'
-C5' H5'1
-C5' H5'2
-C8 H8
-C2 H2
-N1 C6
-C2 N3
-C4 C5
-N7 C8
-[ impropers ]
-N6 C6 H61 H62
-C6 N1 C5 N6
-
-
-[ RA3 ]
- ; H61 H62;
- ; \ /
- ; N6
- ; |
- ; C6
- ; // \
- ; N1 C5--N7\\
- ; | || C8-H8
- ; C2 C4--N9/
- ; / \\ / \
- ; H2 N3 \
- ; \
- ; \
- ; \
- ; O1P H5'1 H4' O4' \
- ; | | \ / \ \
- ; -P-O5'-C5'---C4' C1'
- ; | | \ / \
- ; O2P H5'2 C3'--C2' H1'
- ; / \ / \
- ; O3' H3' O2' H2'2
- ; | |
- ; H3T H2'1
- ;
-[ atoms ]
-P P 1.50 0
-O1P ON3 -0.78 1
-O2P ON3 -0.78 2
-O5' ON2 -0.57 3
-C5' CN8B -0.08 4
-H5'1 HN8 0.09 5
-H5'2 HN8 0.09 6
-C4' CN7 0.16 7
-H4' HN7 0.09 8
-O4' ON6B -0.50 9
-C1' CN7B 0.16 10
-H1' HN7 0.09 11
-N9 NN2 -0.05 12
-C5 CN5 0.28 13
-N7 NN4 -0.71 14
-C8 CN4 0.34 15
-H8 HN3 0.12 16
-N1 NN3A -0.74 17
-C2 CN4 0.50 18
-H2 HN3 0.13 19
-N3 NN3A -0.75 20
-C4 CN5 0.43 21
-C6 CN2 0.46 22
-N6 NN1 -0.77 23
-H61 HN1 0.38 24
-H62 HN1 0.38 25
-C2' CN7B 0.14 26
-H2'2 HN7 0.09 27
-O2' ON5 -0.66 28
-H2'1 HN5 0.43 29
-C3' CN7 0.14 30
-H3' HN7 0.09 31
-O3' ON5 -0.66 32
-H3T HN5 0.43 33
-[ bonds ]
--O3' P
-P O1P
-P O2P
-P O5'
-O5' C5'
-C5' C4'
-C4' O4'
-C4' C3'
-O4' C1'
-C1' N9
-C1' C2'
-N9 C4
-N9 C8
-C4 N3
-C2 N1
-C6 N6
-N6 H61
-N6 H62
-C6 C5
-C5 N7
-C2' C3'
-C2' O2'
-O2' H2'1
-C3' O3'
-O3' H3T
-C1' H1'
-C2' H2'2
-C3' H3'
-C4' H4'
-C5' H5'1
-C5' H5'2
-C8 H8
-C2 H2
-N1 C6
-C2 N3
-C4 C5
-N7 C8
-[ impropers ]
-N6 C6 H61 H62
-C6 N1 C5 N6
-
;--------------------------------------------------------------------------
[ RC ]
;
; | |
; H2'1
[ atoms ]
-P P 1.50 0
-O1P ON3 -0.78 1
-O2P ON3 -0.78 2
-O5' ON2 -0.57 3
-C5' CN8B -0.08 4
-H5'1 HN8 0.09 5
-H5'2 HN8 0.09 6
-C4' CN7 0.16 7
-H4' HN7 0.09 8
-O4' ON6B -0.50 9
-C1' CN7B 0.16 10
-H1' HN7 0.09 11
-N1 NN2 -0.13 12
-C6 CN3 0.05 13
-H6 HN3 0.17 14
-C5 CN3 -0.13 15
-H5 HN3 0.07 16
-C2 CN1 0.52 17
-O2 ON1C -0.49 18
-N3 NN3 -0.66 19
-C4 CN2 0.65 20
-N4 NN1 -0.75 21
-H41 HN1 0.37 22
-H42 HN1 0.33 23
-C2' CN7B 0.14 24
-H2'2 HN7 0.09 25
-O2' ON5 -0.66 26
-H2'1 HN5 0.43 27
-C3' CN7 0.01 28
-H3' HN7 0.09 29
-O3' ON2 -0.57 30
-[ bonds ]
--O3' P
-P O1P
-P O2P
-P O5'
-O5' C5'
-C5' C4'
-C4' O4'
-C4' C3'
-O4' C1'
-C1' N1
-C1' C2'
-N1 C2
-N1 C6
-C2 N3
-C4 N4
-N4 H41
-N4 H42
-C4 C5
-C2' C3'
-C3' O3'
-C2' O2'
-O2' H2'1
-C1' H1'
-C2' H2'2
-C3' H3'
-C4' H4'
-C5' H5'1
-C5' H5'2
-C5 H5
-C6 H6
-C2 O2
-C5 C6
-N3 C4
-[ impropers ]
-C2 N1 N3 O2
-C4 N3 C5 N4
-N4 C4 H41 H42
-
-[ RC5 ]
-;
-; H42 H41
-; \ /
-; N4
-; |
-; C4
-; / \\
-; H5-C5 N3
-; || |
-; H6-C6 C2
-; \ / \\
-; N1 O2
-; \
-; \
-; \
-; H5'1H4' O4' \
-; | \ / \ \
-; H5T-O5'-C5'---C4' C1'
-; | \ / \
-; H5'2 C3'--C2' H1'
-; / \ / \
-; O3' H3' O2' H2'2
-; | |
-; H2'1
-[ atoms ]
-H5T HN5 0.43 0
-O5' ON5 -0.66 1
-C5' CN8B 0.05 2
-H5'1 HN8 0.09 3
-H5'2 HN8 0.09 4
-C4' CN7 0.16 5
-H4' HN7 0.09 6
-O4' ON6B -0.50 7
-C1' CN7B 0.16 8
-H1' HN7 0.09 9
-N1 NN2 -0.13 10
-C6 CN3 0.05 11
-H6 HN3 0.17 12
-C5 CN3 -0.13 13
-H5 HN3 0.07 14
-C2 CN1 0.52 15
-O2 ON1C -0.49 16
-N3 NN3 -0.66 17
-C4 CN2 0.65 18
-N4 NN1 -0.75 19
-H41 HN1 0.37 20
-H42 HN1 0.33 21
-C2' CN7B 0.14 22
-H2'2 HN7 0.09 23
-O2' ON5 -0.66 24
-H2'1 HN5 0.43 25
-C3' CN7 0.01 26
-H3' HN7 0.09 27
-O3' ON2 -0.57 28
-[ bonds ]
-H5T O5'
-O5' C5'
-C5' C4'
-C4' O4'
-C4' C3'
-O4' C1'
-C1' N1
-C1' C2'
-N1 C2
-N1 C6
-C2 N3
-C4 N4
-N4 H41
-N4 H42
-C4 C5
-C2' C3'
-C3' O3'
-C2' O2'
-O2' H2'1
-C1' H1'
-C2' H2'2
-C3' H3'
-C4' H4'
-C5' H5'1
-C5' H5'2
-C5 H5
-C6 H6
-C2 O2
-C5 C6
-N3 C4
-[ impropers ]
-C2 N1 N3 O2
-C4 N3 C5 N4
-N4 C4 H41 H42
-
-[ RC3 ]
-;
-; H42 H41
-; \ /
-; N4
-; |
-; C4
-; / \\
-; H5-C5 N3
-; || |
-; H6-C6 C2
-; \ / \\
-; N1 O2
-; \
-; \
-; \
-; O1P H5'1H4' O4' \
-; | | \ / \ \
-; -P-O5'-C5'---C4' C1'
-; | | \ / \
-; O2P H5'2 C3'--C2' H1'
-; / \ / \
-; O3' H3' O2' H2'2
-; | |
-; H3T H2'1
-[ atoms ]
-P P 1.50 0
-O1P ON3 -0.78 1
-O2P ON3 -0.78 2
-O5' ON2 -0.57 3
-C5' CN8B -0.08 4
-H5'1 HN8 0.09 5
-H5'2 HN8 0.09 6
-C4' CN7 0.16 7
-H4' HN7 0.09 8
-O4' ON6B -0.50 9
-C1' CN7B 0.16 10
-H1' HN7 0.09 11
-N1 NN2 -0.13 12
-C6 CN3 0.05 13
-H6 HN3 0.17 14
-C5 CN3 -0.13 15
-H5 HN3 0.07 16
-C2 CN1 0.52 17
-O2 ON1C -0.49 18
-N3 NN3 -0.66 19
-C4 CN2 0.65 20
-N4 NN1 -0.75 21
-H41 HN1 0.37 22
-H42 HN1 0.33 23
-C2' CN7B 0.14 24
-H2'2 HN7 0.09 25
-O2' ON5 -0.66 26
-H2'1 HN5 0.43 27
-C3' CN7 0.14 28
-H3' HN7 0.09 29
-O3' ON5 -0.66 30
-H3T HN5 0.43 31
-[ bonds ]
--O3' P
-P O1P
-P O2P
-P O5'
-O5' C5'
-C5' C4'
-C4' O4'
-C4' C3'
-O4' C1'
-C1' N1
-C1' C2'
-N1 C2
-N1 C6
-C2 N3
-C4 N4
-N4 H41
-N4 H42
-C4 C5
-C2' C3'
-C3' O3'
-O3' H3T
-C2' O2'
-O2' H2'1
-C1' H1'
-C2' H2'2
-C3' H3'
-C4' H4'
-C5' H5'1
-C5' H5'2
-C5 H5
-C6 H6
-C2 O2
-C5 C6
-N3 C4
-[ impropers ]
-C2 N1 N3 O2
-C4 N3 C5 N4
-N4 C4 H41 H42
-
-; --------------------------------------------------------------------
-[ RG ]
-; O6
-; ||
-; C6
-; / \
-; H1-N1 C5--N7\\
-; | || C8-H8
-; C2 C4--N9/
-; / \\ / \
-; H21-N2 N3 \
-; | \
-; H22 \
-; \
-; O1P H5'1 H4' O4' \
-; | | \ / \ \
-; -P-O5'-C5'---C4' C1'
-; | | \ / \
-; O2P H5'2 C3'--C2' H1'
-; / \ / \
-; O3' H3' O2' H2'2
-; | |
-; H2'1
-[ atoms ]
-P P 1.50 0
-O1P ON3 -0.78 1
-O2P ON3 -0.78 2
-O5' ON2 -0.57 3
-C5' CN8B -0.08 4
-H5'1 HN8 0.09 5
-H5'2 HN8 0.09 6
-C4' CN7 0.16 7
-H4' HN7 0.09 8
-O4' ON6B -0.50 9
-C1' CN7B 0.16 10
-H1' HN7 0.09 11
-N9 NN2B -0.02 12
-C4 CN5 0.26 13
-N2 NN1 -0.68 14
-H21 HN1 0.32 15
-H22 HN1 0.35 16
-N3 NN3G -0.74 17
-C2 CN2 0.75 18
-N1 NN2G -0.34 19
-H1 HN2 0.26 20
-C6 CN1 0.54 21
-O6 ON1 -0.51 22
-C5 CN5G 0.00 23
-N7 NN4 -0.60 24
-C8 CN4 0.25 25
-H8 HN3 0.16 26
-C2' CN7B 0.14 27
-H2'2 HN7 0.09 28
-O2' ON5 -0.66 29
-H2'1 HN5 0.43 30
-C3' CN7 0.01 31
-H3' HN7 0.09 32
-O3' ON2 -0.57 33
+P P 1.50 0
+O1P ON3 -0.78 1
+O2P ON3 -0.78 2
+O5' ON2 -0.57 3
+C5' CN8B -0.08 4
+H5'1 HN8 0.09 5
+H5'2 HN8 0.09 6
+C4' CN7 0.16 7
+H4' HN7 0.09 8
+O4' ON6B -0.50 9
+C1' CN7B 0.16 10
+H1' HN7 0.09 11
+N1 NN2 -0.13 12
+C6 CN3 0.05 13
+H6 HN3 0.17 14
+C5 CN3 -0.13 15
+H5 HN3 0.07 16
+C2 CN1 0.52 17
+O2 ON1C -0.49 18
+N3 NN3 -0.66 19
+C4 CN2 0.65 20
+N4 NN1 -0.75 21
+H41 HN1 0.37 22
+H42 HN1 0.33 23
+C2' CN7B 0.14 24
+H2'2 HN7 0.09 25
+O2' ON5 -0.66 26
+H2'1 HN5 0.43 27
+C3' CN7 0.01 28
+H3' HN7 0.09 29
+O3' ON2 -0.57 30
[ bonds ]
-O3' P
P O1P
C4' O4'
C4' C3'
O4' C1'
-C1' N9
+C1' N1
C1' C2'
-N9 C4
-N9 C8
-C4 N3
-C2 N2
-C2 N1
-N2 H21
-N2 H22
-N1 H1
+N1 C2
N1 C6
-C6 C5
-C5 N7
-C2' C3'
-C3' O3'
-C2' O2'
-O2' H2'1
-C1' H1'
-C2' H2'2
-C3' H3'
-C4' H4'
-C5' H5'1
-C5' H5'2
-C8 H8
C2 N3
+C4 N4
+N4 H41
+N4 H42
C4 C5
-N7 C8
-C6 O6
-[ impropers ]
-C2 N3 N1 N2
-C6 N1 C5 O6
-N2 H21 C2 H22
-
-[ RG5 ]
-; O6
-; ||
-; C6
-; / \
-; H1-N1 C5--N7\\
-; | || C8-H8
-; C2 C4--N9/
-; / \\ / \
-; H21-N2 N3 \
-; | \
-; H22 \
-; \
-; H5'1H4' O4' \
-; | \ / \ \
-; H5T-O5'-C5'---C4' C1'
-; | \ / \
-; H5'2 C3'--C2' H1'
-; / \ / \
-; O3' H3' O2' H2'2
-; | |
-; H2'1
-[ atoms ]
-H5T HN5 0.43 0
-O5' ON5 -0.66 1
-C5' CN8B 0.05 2
-H5'1 HN8 0.09 3
-H5'2 HN8 0.09 4
-C4' CN7 0.16 5
-H4' HN7 0.09 6
-O4' ON6B -0.50 7
-C1' CN7B 0.16 8
-H1' HN7 0.09 9
-N9 NN2B -0.02 10
-C4 CN5 0.26 11
-N2 NN1 -0.68 12
-H21 HN1 0.32 13
-H22 HN1 0.35 14
-N3 NN3G -0.74 15
-C2 CN2 0.75 16
-N1 NN2G -0.34 17
-H1 HN2 0.26 18
-C6 CN1 0.54 19
-O6 ON1 -0.51 20
-C5 CN5G 0.00 21
-N7 NN4 -0.60 22
-C8 CN4 0.25 23
-H8 HN3 0.16 24
-C2' CN7B 0.14 25
-H2'2 HN7 0.09 26
-O2' ON5 -0.66 27
-H2'1 HN5 0.43 28
-C3' CN7 0.01 29
-H3' HN7 0.09 30
-O3' ON2 -0.57 31
-[ bonds ]
-H5T O5'
-O5' C5'
-C5' C4'
-C4' O4'
-C4' C3'
-O4' C1'
-C1' N9
-C1' C2'
-N9 C4
-N9 C8
-C4 N3
-C2 N2
-C2 N1
-N2 H21
-N2 H22
-N1 H1
-N1 C6
-C6 C5
-C5 N7
C2' C3'
C3' O3'
C2' O2'
C4' H4'
C5' H5'1
C5' H5'2
-C8 H8
-C2 N3
-C4 C5
-N7 C8
-C6 O6
+C5 H5
+C6 H6
+C2 O2
+C5 C6
+N3 C4
[ impropers ]
-C2 N3 N1 N2
-C6 N1 C5 O6
-N2 H21 C2 H22
-
-[ RG3 ]
+C2 N1 N3 O2
+C4 N3 C5 N4
+N4 C4 H41 H42
+
+; --------------------------------------------------------------------
+[ RG ]
; O6
; ||
; C6
; / \ / \
; O3' H3' O2' H2'2
; | |
-; H3T H2'1
+; H2'1
[ atoms ]
P P 1.50 0
O1P ON3 -0.78 1
H2'2 HN7 0.09 28
O2' ON5 -0.66 29
H2'1 HN5 0.43 30
-C3' CN7 0.14 31
+C3' CN7 0.01 31
H3' HN7 0.09 32
-O3' ON5 -0.66 33
-H3T HN5 0.43 34
+O3' ON2 -0.57 33
[ bonds ]
-O3' P
P O1P
C5 N7
C2' C3'
C3' O3'
-O3' H3T
C2' O2'
O2' H2'1
C1' H1'
[ impropers ]
C2 N1 N3 O2
C4 N3 C5 O4
-
-[ RU5 ]
- ; O4
- ; ||
- ; C4 H3
- ; / \ /
- ; H5-C5 N3
- ; || |
- ; H6-C6 C2
- ; \ / \\
- ; N1 O2
- ; \
- ; \
- ; \
- ; H5'1 H4' O4' \
- ; | \ / \ \
- ; H5T-O5'-C5'---C4' C1'
- ; | \ / \
- ; H5'2 C3'--C2' H1'
- ; / \ / \
- ; O3' H3' O2' H2'2
- ; | |
- ; H2'1
- ;
-[ atoms ]
-H5T HN5 0.43 0
-O5' ON5 -0.66 1
-C5' CN8B 0.05 2
-H5'1 HN8 0.09 3
-H5'2 HN8 0.09 4
-C4' CN7 0.16 5
-H4' HN7 0.09 6
-O4' ON6B -0.50 7
-C1' CN7B 0.16 8
-H1' HN7 0.09 9
-N1 NN2B -0.34 10
-C6 CN3 0.20 11
-H6 HN3 0.14 12
-C2 CN1T 0.55 13
-O2 ON1 -0.45 14
-N3 NN2U -0.46 15
-H3 HN2 0.36 16
-C4 CN1 0.53 17
-O4 ON1 -0.48 18
-C5 CN3 -0.15 19
-H5 HN3 0.10 20
-C2' CN7B 0.14 21
-H2'2 HN7 0.09 22
-O2' ON5 -0.66 23
-H2'1 HN5 0.43 24
-C3' CN7 0.01 25
-H3' HN7 0.09 26
-O3' ON2 -0.57 27
-[ bonds ]
-H5T O5'
-O5' C5'
-C5' C4'
-C4' O4'
-C4' C3'
-O4' C1'
-C1' N1
-C1' C2'
-N1 C2
-N1 C6
-C2 N3
-N3 H3
-N3 C4
-C4 C5
-C2' C3'
-C3' O3'
-C2' O2'
-O2' H2'1
-C1' H1'
-C2' H2'2
-C3' H3'
-C4' H4'
-C5' H5'1
-C5' H5'2
-C5 H5
-C6 H6
-C2 O2
-C4 O4
-C5 C6
-[ impropers ]
-C2 N1 N3 O2
-C4 N3 C5 O4
-
-[ RU3 ]
- ; O4
- ; ||
- ; C4 H3
- ; / \ /
- ; H5-C5 N3
- ; || |
- ; H6-C6 C2
- ; \ / \\
- ; N1 O2
- ; \
- ; \
- ; \
- ; O1P H5'1H4' O4' \
- ; | | \ / \ \
- ; -P-O5'-C5'---C4' C1'
- ; | | \ / \
- ; O2P H5'2 C3'--C2' H1'
- ; / \ / \
- ; O3' H3' O2' H2'2
- ; | |
- ; H3T H2'1
- ;
-[ atoms ]
-P P 1.50 0
-O1P ON3 -0.78 1
-O2P ON3 -0.78 2
-O5' ON2 -0.57 3
-C5' CN8B -0.08 4
-H5'1 HN8 0.09 5
-H5'2 HN8 0.09 6
-C4' CN7 0.16 7
-H4' HN7 0.09 8
-O4' ON6B -0.50 9
-C1' CN7B 0.16 10
-H1' HN7 0.09 11
-N1 NN2B -0.34 12
-C6 CN3 0.20 13
-H6 HN3 0.14 14
-C2 CN1T 0.55 15
-O2 ON1 -0.45 16
-N3 NN2U -0.46 17
-H3 HN2 0.36 18
-C4 CN1 0.53 19
-O4 ON1 -0.48 20
-C5 CN3 -0.15 21
-H5 HN3 0.10 22
-C2' CN7B 0.14 23
-H2'2 HN7 0.09 24
-O2' ON5 -0.66 25
-H2'1 HN5 0.43 26
-C3' CN7 0.14 27
-H3' HN7 0.09 28
-O3' ON5 -0.66 29
-H3T HN5 0.43 30
-[ bonds ]
--O3' P
-P O1P
-P O2P
-P O5'
-O5' C5'
-C5' C4'
-C4' O4'
-C4' C3'
-O4' C1'
-C1' N1
-C1' C2'
-N1 C2
-N1 C6
-C2 N3
-N3 H3
-N3 C4
-C4 C5
-C2' C3'
-C3' O3'
-O3' H3T
-C2' O2'
-O2' H2'1
-C1' H1'
-C2' H2'2
-C3' H3'
-C4' H4'
-C5' H5'1
-C5' H5'2
-C5 H5
-C6 H6
-C2 O2
-C4 O4
-C5 C6
-[ impropers ]
-C2 N1 N3 O2
-C4 N3 C5 O4
-363
+365
��ߦ��ߨ���߬�����������ߦ��߷���ߋ��߶�ߦ�����������������߶��
�߳���ߋ��߳���߫���ߨ���߫������������
�����߽����߲�߷������ײ��������
�����،ߑ�߈��߆��ߜ��ߍ���ߐ�ߞ�ߚ���������������߸��������
�ߓ���ߋ�߈����ߋ���߶ߙ���ߓ���߶ߛ�ߌ�������������������
���߶ߗ���ߚ���������ߓ�����ߋ���ߚ���������ߚ�������߯������
+�����ߐ�ߜ�����������ߞ��ߋ��ߌ������߲�ߌ������ߖ�߈�������ߑ�����ߜ��������ײ�������
+��،ߊ����ߜ���ߋ���ߐ���߆��ߞ��߶ߔ����״���߽����
[ atoms ]
; id at type res nr residu name at name cg nr charge mass
-1 CU2+ 1 CU2+ CU 1 2 63.54600
+1 Cu2+ 1 CU2+ CU 1 2 63.54600
[ moleculetype ]
; molname nrexcl
[ atoms ]
; id at type res nr residu name at name cg nr charge mass
-1 ZN2+ 1 ZN2+ ZN 1 2 65.37000
+1 Zn2+ 1 ZN2+ ZN 1 2 65.37000
[ moleculetype ]
; molname nrexcl
endif()
endif(GMX_X86_64_ASM)
+if(GMX_FORTRAN)
+ if (GMX_DOUBLE)
+ file(GLOB FORTRAN_SOURCES nonbonded/nb_kernel_f77_double/*.[cf])
+ else(GMX_DOUBLE)
+ file(GLOB FORTRAN_SOURCES nonbonded/nb_kernel_f77_single/*.[cf])
+ endif(GMX_DOUBLE)
+endif(GMX_FORTRAN)
+
+if(GMX_POWER6)
+ file(GLOB FORTRAN_SOURCES nonbonded/nb_kernel_power6/*.[cF])
+endif(GMX_POWER6)
+
if(NOT GMX_EXTERNAL_BLAS)
file(GLOB BLAS_SOURCES gmx_blas/*.c)
endif(NOT GMX_EXTERNAL_BLAS)
endif(GMX_ASM_USEASM-NASM)
endif(NOT GMX_OPENMM)
-add_library(gmx ${GMXLIB_SOURCES} ${BLAS_SOURCES} ${LAPACK_SOURCES} ${GMX_SSEKERNEL_C_SRC} ${GMX_SSEKERNEL_ASM_SRC} ${THREAD_MPI_SRC})
+add_library(gmx ${GMXLIB_SOURCES} ${BLAS_SOURCES} ${LAPACK_SOURCES} ${GMX_SSEKERNEL_C_SRC} ${GMX_SSEKERNEL_ASM_SRC} ${FORTRAN_SOURCES} ${THREAD_MPI_SRC})
target_link_libraries(gmx ${GMX_EXTRA_LIBRARIES} ${THREAD_LIB})
add_dependencies(gmx gmx_version)
set_target_properties(gmx PROPERTIES OUTPUT_NAME "gmx${GMX_LIBS_SUFFIX}" SOVERSION ${SOVERSION} INSTALL_NAME_DIR "${LIB_INSTALL_DIR}")
#
#
-libgmx@LIBSUFFIX@_la_LDFLAGS = -no-undefined -version-info @SHARED_VERSION_INFO@ $(PTHREAD_LIBS)
+libgmx@LIBSUFFIX@_la_LDFLAGS = -no-undefined -version-info @SHARED_VERSION_INFO@ @DLOPEN_LIBS@ $(PTHREAD_LIBS)
libgmx@LIBSUFFIX@_la_SOURCES = \
3dview.c atomprop.c bondfree.c \
int natoms,ngtc,nnhpres,nhchainlength,fflags,flags_eks,flags_enh;
int d;
int ret;
- gmx_file_position_t *outputfiles;
- int nfiles;
- t_fileio *chksum_file;
- FILE* fplog = *pfplog;
- unsigned char digest[16];
+ gmx_file_position_t *outputfiles;
+ int nfiles;
+ t_fileio *chksum_file;
+ FILE* fplog = *pfplog;
+ unsigned char digest[16];
#if !((defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64) && !defined __CYGWIN__ && !defined __CYGWIN32__)
- struct flock fl = { 0, SEEK_SET, 0, F_WRLCK, 0 };
+ struct flock fl; /* don't initialize here: the struct order is OS
+ dependent! */
#endif
-
+
const char *int_warn=
- "WARNING: The checkpoint file was generator with integrator %s,\n"
- " while the simulation uses integrator %s\n\n";
+ "WARNING: The checkpoint file was generated with integrator %s,\n"
+ " while the simulation uses integrator %s\n\n";
const char *sd_note=
"NOTE: The checkpoint file was for %d nodes doing SD or BD,\n"
" while the simulation uses %d SD or BD nodes,\n"
" continuation will be exact, except for the random state\n\n";
+#if !((defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64) && !defined __CYGWIN__ && !defined __CYGWIN32__)
+ fl.l_type=F_WRLCK;
+ fl.l_whence=SEEK_SET;
+ fl.l_start=0;
+ fl.l_len=0;
+ fl.l_pid=0;
+#endif
+
if (PARTDECOMP(cr))
{
gmx_fatal(FARGS,
if (outputfiles[i].chksum_size != -1)
{
if (gmx_fio_get_file_md5(chksum_file,outputfiles[i].offset,
- digest) != outputfiles[i].chksum_size)
+ digest) != outputfiles[i].chksum_size) /*at the end of the call the file position is at the end of the file*/
{
gmx_fatal(FARGS,"Can't read %d bytes of '%s' to compute checksum. The file has been replaced or its contents has been modified.",
outputfiles[i].chksum_size,
outputfiles[i].filename);
}
}
- else if (i==0) /*log file need to be seeked even when not reading md5*/
+ if (i==0) /*log file needs to be seeked in case we need to truncate (other files are truncated below)*/
{
- gmx_fio_seek(chksum_file,outputfiles[i].offset);
+ if (gmx_fio_seek(chksum_file,outputfiles[i].offset))
+ {
+ gmx_fatal(FARGS,"Seek error! Failed to truncate log-file: %s.", strerror(errno));
+ }
}
#endif
"GROMACS 4: Algorithms for highly efficient, load-balanced, and scalable molecular simulation",
"J. Chem. Theory Comput.",
4, 2008, "435-447" },
+ { "Hub2010",
+ "J. S. Hub, B. L. de Groot and D. van der Spoel",
+ "g_wham - A free weighted histogram analysis implementation including robust error and autocorrelation estimates",
+ "J. Chem. Theory Comput.",
+ 0, 2010, "0000-0000"},
{ "In-Chul99a",
"Y. In-Chul and M. L. Berkowitz",
"Ewald summation for systems with slab geometry",
+++ /dev/null
-/*
- *
- * This source code is part of
- *
- * G R O M A C S
- *
- * GROningen MAchine for Chemical Simulations
- *
- * VERSION 3.2.0
- * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
- * 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.
-
- * 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:
- * GROningen Mixture of Alchemy and Childrens' Stories
- */
-/* This file is completely threadsafe - keep it that way! */
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-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;
-}
gmx_fio_lock(fio);
if (fio->fp)
{
- gmx_fseek(fio->fp, fpos, SEEK_SET);
+ rc = gmx_fseek(fio->fp, fpos, SEEK_SET);
}
else
{
return rc;
}
+/* Return the size of the arrays */
+int
+gmx_residuetype_get_size(gmx_residuetype_t rt)
+{
+ return rt->n;
+}
+
+/* Search for a residuetype with name resnm within the
+ * gmx_residuetype database. Return the index if found,
+ * otherwise -1.
+ */
+int
+gmx_residuetype_get_index(gmx_residuetype_t rt, const char *resnm)
+{
+ int i,rc;
+
+ rc=-1;
+ for(i=0;i<rt->n && rc;i++)
+ {
+ rc=gmx_strcasecmp(rt->resname[i],resnm);
+ }
+
+ return (0 == rc) ? i-1 : -1;
+}
+
+/* Return the name of the residuetype with the given index, or
+ * NULL if not found. */
+const char *
+gmx_residuetype_get_name(gmx_residuetype_t rt, int index)
+{
+ if(index >= 0 && index < rt->n) {
+ return rt->resname[index];
+ } else {
+ return NULL;
+ }
+}
};
const char *esa_names[esaNR+1] = {
- "Ace-approx", "None", "Still", NULL
+ "Ace-approximation", "None", "Still", NULL
};
const char *ewt_names[ewtNR+1] = {
}
}
}
+ /* Clear the values for dynamic output to avoid valgrind warnings. */
+ if ((sel->flags & SEL_DYNAMIC) && sel->v.type == REAL_VALUE)
+ {
+ int i;
+
+ for (i = 0; i < sel->v.nr; ++i)
+ {
+ sel->v.u.r[i] = 0.0;
+ }
+ }
}
return 0;
if (left->mempool)
{
_gmx_selvalue_setstore(&left->v, sel->v.u.ptr);
- rc = _gmx_selelem_mempool_reserve(right, g->isize);
- if (rc != 0)
+ if (right)
{
- return rc;
+ rc = _gmx_selelem_mempool_reserve(right, g->isize);
+ if (rc != 0)
+ {
+ return rc;
+ }
}
}
- else if (right->mempool)
+ else if (right && right->mempool)
{
_gmx_selvalue_setstore(&right->v, sel->v.u.ptr);
}
if (left->mempool)
{
_gmx_selvalue_setstore(&left->v, NULL);
- _gmx_selelem_mempool_release(right);
+ if (right)
+ {
+ _gmx_selelem_mempool_release(right);
+ }
}
- else if (right->mempool)
+ else if (right && right->mempool)
{
_gmx_selvalue_setstore(&right->v, NULL);
}
OR = 286,
AND = 287,
NOT = 288,
- UNARY_NEG = 289
+ UNARY_NEG = 289,
+ NUM_REDUCT = 290
};
#endif
/* Tokens. */
#define AND 287
#define NOT 288
#define UNARY_NEG 289
+#define NUM_REDUCT 290
struct t_selexpr_param *param;
}
/* Line 187 of yacc.c. */
-#line 212 "parser.c"
+#line 214 "parser.c"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
/* Line 216 of yacc.c. */
-#line 225 "parser.c"
+#line 227 "parser.c"
#ifdef short
# undef short
/* YYFINAL -- State number of the termination state. */
#define YYFINAL 2
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 329
+#define YYLAST 417
/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 44
+#define YYNTOKENS 49
/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 20
+#define YYNNTS 26
/* YYNRULES -- Number of rules. */
-#define YYNRULES 76
+#define YYNRULES 91
/* YYNRULES -- Number of states. */
-#define YYNSTATES 125
+#define YYNSTATES 150
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
#define YYUNDEFTOK 2
-#define YYMAXUTOK 289
+#define YYMAXUTOK 290
#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 41, 42, 36, 34, 43, 35, 2, 37, 2, 2,
+ 42, 43, 36, 34, 45, 35, 2, 37, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 40, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 41, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 39, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 44, 2, 46, 39, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 47, 2, 48, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 26, 27, 28, 29, 30, 31, 32, 33, 38
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 38,
+ 40
};
#if YYDEBUG
/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
YYRHS. */
-static const yytype_uint8 yyprhs[] =
+static const yytype_uint16 yyprhs[] =
{
0, 0, 3, 4, 7, 10, 13, 14, 16, 18,
20, 22, 25, 29, 33, 37, 39, 41, 44, 47,
- 49, 51, 55, 59, 61, 63, 65, 67, 70, 74,
- 78, 82, 86, 89, 92, 94, 96, 99, 103, 107,
- 111, 113, 115, 118, 122, 126, 130, 134, 138, 141,
- 145, 149, 151, 154, 162, 166, 169, 173, 175, 177,
- 179, 181, 184, 185, 188, 191, 192, 194, 196, 199,
- 203, 205, 207, 209, 211, 215, 219
+ 49, 51, 55, 59, 61, 64, 66, 69, 71, 73,
+ 75, 77, 80, 84, 88, 92, 96, 99, 102, 104,
+ 106, 109, 113, 117, 121, 123, 125, 128, 132, 136,
+ 140, 144, 148, 151, 155, 159, 161, 164, 172, 176,
+ 179, 183, 185, 187, 189, 191, 194, 195, 198, 201,
+ 202, 204, 208, 210, 213, 217, 219, 223, 225, 228,
+ 232, 234, 236, 238, 240, 242, 244, 246, 248, 250,
+ 254, 258
};
/* YYRHS -- A `-1'-separated list of the rules' RHS. */
static const yytype_int8 yyrhs[] =
{
- 45, 0, -1, -1, 45, 46, -1, 47, 10, -1,
- 1, 10, -1, -1, 48, -1, 6, -1, 52, -1,
- 50, -1, 52, 50, -1, 9, 40, 53, -1, 9,
- 40, 55, -1, 9, 40, 57, -1, 4, -1, 49,
- -1, 4, 5, -1, 49, 5, -1, 57, -1, 53,
- -1, 41, 50, 42, -1, 50, 23, 58, -1, 6,
- -1, 7, -1, 8, -1, 9, -1, 33, 53, -1,
- 53, 32, 53, -1, 53, 31, 53, -1, 41, 53,
- 42, -1, 55, 28, 55, -1, 11, 52, -1, 11,
- 6, -1, 24, -1, 18, -1, 54, 19, -1, 54,
- 17, 62, -1, 54, 16, 62, -1, 54, 21, 58,
- -1, 6, -1, 7, -1, 54, 16, -1, 54, 20,
- 58, -1, 55, 34, 55, -1, 55, 35, 55, -1,
- 55, 36, 55, -1, 55, 37, 55, -1, 35, 55,
- -1, 55, 39, 55, -1, 41, 55, 42, -1, 52,
- -1, 54, 17, -1, 41, 51, 43, 51, 43, 51,
- 42, -1, 41, 57, 42, -1, 22, 58, -1, 18,
- 27, 53, -1, 14, -1, 13, -1, 15, -1, 59,
- -1, 59, 26, -1, -1, 59, 60, -1, 25, 61,
- -1, -1, 62, -1, 63, -1, 62, 63, -1, 62,
- 43, 63, -1, 53, -1, 57, -1, 55, -1, 56,
- -1, 6, 12, 6, -1, 6, 12, 7, -1, 7,
- 12, 51, -1
+ 50, 0, -1, -1, 50, 51, -1, 52, 10, -1,
+ 1, 10, -1, -1, 53, -1, 6, -1, 59, -1,
+ 55, -1, 59, 55, -1, 9, 41, 60, -1, 9,
+ 41, 62, -1, 9, 41, 64, -1, 4, -1, 54,
+ -1, 4, 5, -1, 54, 5, -1, 64, -1, 60,
+ -1, 42, 55, 43, -1, 55, 23, 65, -1, 6,
+ -1, 35, 6, -1, 7, -1, 35, 7, -1, 56,
+ -1, 57, -1, 8, -1, 9, -1, 33, 60, -1,
+ 60, 32, 60, -1, 60, 31, 60, -1, 42, 60,
+ 43, -1, 62, 28, 62, -1, 11, 59, -1, 11,
+ 6, -1, 24, -1, 18, -1, 61, 19, -1, 61,
+ 17, 70, -1, 61, 16, 70, -1, 61, 21, 65,
+ -1, 6, -1, 7, -1, 61, 16, -1, 61, 20,
+ 65, -1, 62, 34, 62, -1, 62, 35, 62, -1,
+ 62, 36, 62, -1, 62, 37, 62, -1, 35, 62,
+ -1, 62, 39, 62, -1, 42, 62, 43, -1, 59,
+ -1, 61, 17, -1, 44, 58, 45, 58, 45, 58,
+ 46, -1, 42, 64, 43, -1, 22, 65, -1, 18,
+ 27, 60, -1, 14, -1, 13, -1, 15, -1, 66,
+ -1, 66, 26, -1, -1, 66, 67, -1, 25, 68,
+ -1, -1, 69, -1, 47, 69, 48, -1, 72, -1,
+ 69, 72, -1, 69, 45, 72, -1, 71, -1, 47,
+ 71, 48, -1, 73, -1, 71, 73, -1, 71, 45,
+ 73, -1, 60, -1, 64, -1, 62, -1, 63, -1,
+ 74, -1, 56, -1, 57, -1, 59, -1, 74, -1,
+ 56, 12, 56, -1, 56, 12, 57, -1, 57, 12,
+ 58, -1
};
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] =
{
- 0, 178, 178, 179, 188, 189, 209, 213, 214, 223,
- 233, 235, 237, 239, 241, 247, 248, 251, 252, 256,
- 257, 262, 263, 274, 275, 278, 279, 287, 293, 299,
- 311, 315, 323, 329, 337, 338, 342, 347, 352, 360,
- 372, 379, 389, 394, 402, 404, 406, 408, 410, 412,
- 414, 421, 428, 440, 445, 449, 457, 468, 472, 476,
- 485, 487, 492, 493, 498, 505, 506, 510, 511, 513,
- 517, 519, 521, 523, 525, 530, 535
+ 0, 182, 182, 183, 192, 193, 213, 217, 218, 227,
+ 237, 239, 241, 243, 245, 251, 252, 255, 256, 260,
+ 261, 266, 267, 279, 280, 284, 285, 288, 289, 292,
+ 293, 301, 307, 313, 325, 329, 337, 343, 351, 352,
+ 356, 361, 366, 374, 386, 393, 403, 408, 416, 418,
+ 420, 422, 424, 426, 428, 435, 442, 454, 459, 463,
+ 471, 482, 486, 490, 499, 501, 506, 507, 512, 519,
+ 520, 521, 525, 526, 528, 533, 534, 538, 539, 541,
+ 545, 547, 549, 551, 553, 557, 562, 567, 572, 576,
+ 581, 586
};
#endif
"KEYWORD_STR", "KEYWORD_POS", "KEYWORD_GROUP", "METHOD_NUMERIC",
"METHOD_GROUP", "METHOD_POS", "MODIFIER", "EMPTY_POSMOD", "PARAM",
"END_OF_METHOD", "OF", "CMP_OP", "PARAM_REDUCT", "XOR", "OR", "AND",
- "NOT", "'+'", "'-'", "'*'", "'/'", "UNARY_NEG", "'^'", "'='", "'('",
- "')'", "','", "$accept", "commands", "command", "cmd_plain",
- "help_request", "help_topic", "selection", "number", "string",
+ "NOT", "'+'", "'-'", "'*'", "'/'", "UNARY_NEG", "'^'", "NUM_REDUCT",
+ "'='", "'('", "')'", "'['", "','", "']'", "'{'", "'}'", "$accept",
+ "commands", "command", "cmd_plain", "help_request", "help_topic",
+ "selection", "integer_number", "real_number", "number", "string",
"sel_expr", "pos_mod", "num_expr", "str_expr", "pos_expr",
"method_params", "method_param_list", "method_param", "value_list",
- "value_list_nonempty", "value_item", 0
+ "value_list_contents", "basic_value_list", "basic_value_list_contents",
+ "value_item", "basic_value_item", "value_item_range", 0
};
#endif
265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
285, 286, 287, 288, 43, 45, 42, 47, 289, 94,
- 61, 40, 41, 44
+ 290, 61, 40, 41, 91, 44, 93, 123, 125
};
# endif
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
static const yytype_uint8 yyr1[] =
{
- 0, 44, 45, 45, 46, 46, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 48, 48, 49, 49, 50,
- 50, 50, 50, 51, 51, 52, 52, 53, 53, 53,
- 53, 53, 53, 53, 54, 54, 53, 53, 53, 53,
- 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
- 55, 56, 56, 57, 57, 57, 57, 53, 55, 57,
- 58, 58, 59, 59, 60, 61, 61, 62, 62, 62,
- 63, 63, 63, 63, 63, 63, 63
+ 0, 49, 50, 50, 51, 51, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 53, 53, 54, 54, 55,
+ 55, 55, 55, 56, 56, 57, 57, 58, 58, 59,
+ 59, 60, 60, 60, 60, 60, 60, 60, 61, 61,
+ 60, 60, 60, 60, 62, 62, 62, 62, 62, 62,
+ 62, 62, 62, 62, 62, 63, 63, 64, 64, 64,
+ 64, 60, 62, 64, 65, 65, 66, 66, 67, 68,
+ 68, 68, 69, 69, 69, 70, 70, 71, 71, 71,
+ 72, 72, 72, 72, 72, 73, 73, 73, 73, 74,
+ 74, 74
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
{
0, 2, 0, 2, 2, 2, 0, 1, 1, 1,
1, 2, 3, 3, 3, 1, 1, 2, 2, 1,
- 1, 3, 3, 1, 1, 1, 1, 2, 3, 3,
- 3, 3, 2, 2, 1, 1, 2, 3, 3, 3,
- 1, 1, 2, 3, 3, 3, 3, 3, 2, 3,
- 3, 1, 2, 7, 3, 2, 3, 1, 1, 1,
- 1, 2, 0, 2, 2, 0, 1, 1, 2, 3,
- 1, 1, 1, 1, 3, 3, 3
+ 1, 3, 3, 1, 2, 1, 2, 1, 1, 1,
+ 1, 2, 3, 3, 3, 3, 2, 2, 1, 1,
+ 2, 3, 3, 3, 1, 1, 2, 3, 3, 3,
+ 3, 3, 2, 3, 3, 1, 2, 7, 3, 2,
+ 3, 1, 1, 1, 1, 2, 0, 2, 2, 0,
+ 1, 3, 1, 2, 3, 1, 3, 1, 2, 3,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
+ 3, 3
};
/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
means the default is an error. */
static const yytype_uint8 yydefact[] =
{
- 2, 0, 1, 0, 15, 40, 41, 25, 26, 0,
- 58, 57, 59, 35, 62, 34, 0, 0, 0, 3,
- 0, 7, 16, 10, 9, 20, 0, 0, 19, 5,
- 17, 0, 33, 26, 32, 0, 55, 60, 40, 35,
- 0, 27, 0, 0, 48, 40, 41, 0, 0, 20,
- 0, 19, 4, 18, 62, 11, 0, 0, 42, 0,
- 36, 62, 62, 0, 0, 0, 0, 0, 0, 0,
- 12, 13, 14, 56, 65, 61, 63, 0, 0, 42,
- 21, 0, 30, 50, 54, 22, 29, 28, 40, 41,
- 51, 70, 0, 72, 73, 71, 38, 67, 37, 43,
- 39, 31, 44, 45, 46, 47, 49, 0, 64, 66,
- 23, 24, 0, 0, 0, 52, 0, 68, 0, 74,
- 75, 76, 69, 0, 53
+ 2, 0, 1, 0, 15, 44, 45, 29, 30, 0,
+ 62, 61, 63, 39, 66, 38, 0, 0, 0, 0,
+ 3, 0, 7, 16, 10, 9, 20, 0, 0, 19,
+ 5, 17, 0, 37, 30, 36, 0, 59, 64, 44,
+ 39, 0, 31, 0, 0, 52, 0, 20, 0, 19,
+ 23, 25, 0, 27, 28, 0, 4, 18, 66, 11,
+ 0, 0, 46, 0, 40, 66, 66, 0, 0, 0,
+ 0, 0, 0, 0, 12, 13, 14, 60, 69, 65,
+ 67, 0, 0, 46, 21, 34, 54, 58, 24, 26,
+ 0, 22, 33, 32, 0, 85, 86, 87, 42, 75,
+ 77, 88, 41, 47, 43, 35, 48, 49, 50, 51,
+ 53, 0, 44, 45, 0, 0, 0, 0, 55, 80,
+ 0, 82, 83, 81, 68, 70, 72, 84, 0, 0,
+ 0, 0, 0, 78, 44, 45, 0, 56, 0, 73,
+ 0, 76, 89, 90, 91, 79, 71, 74, 0, 57
};
/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int8 yydefgoto[] =
{
- -1, 1, 19, 20, 21, 22, 23, 48, 90, 91,
- 26, 93, 94, 95, 36, 37, 76, 108, 98, 97
+ -1, 1, 20, 21, 22, 23, 24, 95, 96, 55,
+ 97, 119, 27, 28, 122, 123, 37, 38, 80, 124,
+ 125, 102, 99, 126, 100, 101
};
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
STATE-NUM. */
-#define YYPACT_NINF -87
+#define YYPACT_NINF -93
static const yytype_int16 yypact[] =
{
- -87, 124, -87, -1, 6, 8, -87, -87, 12, 56,
- -87, -87, -87, 17, -87, -87, 278, 288, 200, -87,
- 53, -87, 75, 66, 225, 0, 133, 84, -87, -87,
- -87, 239, -87, -87, -87, 278, -87, 57, -87, -87,
- 278, -87, 288, -14, 55, 54, 58, -16, 63, -18,
- 68, 69, -87, -87, -87, 66, 278, 278, 186, 186,
- -87, -87, -87, 288, 288, 288, 288, 288, 288, 264,
- 0, 84, -87, 0, 186, -87, -87, -18, 51, -87,
- -87, 102, -87, -87, -87, -87, 83, -87, 110, 114,
- -87, 0, 164, 19, -87, -87, 155, -87, 155, -87,
- -87, 19, 38, 38, 55, 55, 55, 69, -87, 155,
- -87, -87, 93, 107, 102, 186, 186, -87, 102, -87,
- -87, -87, -87, 85, -87
+ -93, 155, -93, 10, 19, 26, -93, -93, -3, 73,
+ -93, -93, -93, 22, -93, -93, 356, 372, 317, 11,
+ -93, 79, -93, 86, 70, 317, 29, 384, 180, -93,
+ -93, -93, 342, -93, -93, -93, 356, -93, 6, -93,
+ -93, 356, -93, 372, -10, 57, -20, -17, 256, 54,
+ -93, -93, 88, -93, -93, 55, -93, -93, -93, 70,
+ 356, 356, 197, 174, -93, -93, -93, 372, 372, 372,
+ 372, 372, 372, 342, 29, 180, -93, 29, 221, -93,
+ -93, -17, 223, -93, -93, -93, -93, -93, -93, -93,
+ 11, -93, 69, -93, 78, 90, 94, -93, -93, 244,
+ -93, -93, -93, -93, -93, 267, 36, 36, 57, 57,
+ 57, 54, 95, 96, 375, 303, 90, 94, -93, 29,
+ 392, 267, -93, -93, -93, 263, -93, -93, 71, 35,
+ 11, 11, 78, -93, 105, 106, 178, 174, 303, -93,
+ 11, -93, -93, -93, -93, -93, -93, -93, 80, -93
};
/* YYPGOTO[NTERM-NUM]. */
static const yytype_int8 yypgoto[] =
{
- -87, -87, -87, -87, -87, -87, 15, -78, 28, 60,
- -17, 3, -87, 4, -46, -87, -87, -87, -57, -86
+ -93, -93, -93, -93, -93, -93, -13, 0, 14, -81,
+ -1, 87, -4, -16, -93, 3, -36, -93, -93, -93,
+ 12, 81, 39, -91, -92, -67
};
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
positive, shift that token. If negative, reduce the rule which
number is the opposite. If zero, do what YYDEFACT says.
If YYTABLE_NINF, syntax error. */
-#define YYTABLE_NINF -25
-static const yytype_int8 yytable[] =
+#define YYTABLE_NINF -27
+static const yytype_int16 yytable[] =
{
- 43, 96, 79, 112, 27, 28, 61, 54, 85, 29,
- 117, 30, 117, 56, 57, 99, 100, 109, -8, 27,
- 44, 50, 51, 117, 82, 43, 80, 27, 28, 24,
- 122, 56, 57, 47, 71, 72, 121, 34, 27, 55,
- 123, 92, 92, 50, 35, 78, 43, 43, 43, 43,
- 43, 43, 31, 64, 65, 66, 67, 92, 68, 27,
- 27, 25, 32, 52, 7, 33, 101, 102, 103, 104,
- 105, 106, 50, 107, 66, 67, 41, 68, 49, 92,
- 53, 92, 74, 75, 25, 64, 65, 66, 67, 54,
- 68, 70, 92, 83, 68, 73, 63, -23, 92, 92,
- 77, -24, 64, 65, 66, 67, 81, 68, 110, 111,
- 83, 84, 63, 119, 120, 57, 86, 87, 64, 65,
- 66, 67, 113, 68, 2, 3, 114, 124, 4, 77,
- 5, 6, 7, 8, -6, 9, 118, 10, 11, 12,
- 0, 0, 13, 0, 0, 0, 14, 0, 15, 58,
- 59, 0, 60, 61, 62, 0, 0, 16, 0, 17,
- 0, 88, 89, 7, 33, 18, 9, 0, 10, 11,
+ 25, 45, 48, 58, 29, 46, 83, 133, 35, 128,
+ 65, 127, 59, 44, 60, 61, 75, 50, 51, 53,
+ 30, 49, 91, 84, 31, 48, 85, 82, 29, 103,
+ 104, 78, 79, 54, 139, 76, -8, 133, 32, 44,
+ 145, 50, 51, 7, 34, 139, 52, 147, 127, 36,
+ 144, 105, 106, 107, 108, 109, 110, 48, 127, 148,
+ 60, 61, 121, 44, 44, 44, 44, 44, 44, 127,
+ 52, 127, 70, 71, 120, 72, 111, 118, 116, 33,
+ 132, 7, 34, 141, 50, 51, 7, 34, 26, 56,
+ 53, 57, 117, 58, 88, 89, 72, 87, 45, 121,
+ 90, 61, 130, 42, 54, 47, 131, -23, -25, 121,
+ 44, 120, 26, 52, 118, 116, 140, -24, -26, 74,
+ 121, 120, 121, 77, 118, 116, 149, 136, 81, 117,
+ 142, 53, 120, 129, 120, 118, 116, 118, 116, 117,
+ 53, 0, 0, 98, 143, 54, 0, 92, 93, 0,
+ 117, 0, 117, 0, 54, 2, 3, 0, 0, 4,
+ 81, 5, 6, 7, 8, -6, 9, 0, 10, 11,
12, 0, 0, 13, 0, 0, 0, 14, 0, 15,
- 58, 115, 0, 60, 61, 62, 0, 0, 16, 0,
- 17, 0, 88, 89, 7, 33, 69, 9, 116, 10,
- 11, 12, 0, 0, 13, 0, 45, 46, 14, 0,
- 15, 9, 0, 10, 11, 12, 0, 0, 13, 16,
- 0, 17, 14, 0, 15, 0, 0, 69, 0, 0,
- 0, 38, 6, 16, 0, 17, 9, 0, 10, 11,
- 12, 18, 0, 13, 0, 38, 6, 14, 0, 15,
- 9, 0, 10, 11, 12, 0, 0, 13, 16, 0,
- 17, 14, 0, 15, 0, 0, 18, 0, 0, 0,
- 45, 46, 16, 0, 17, 9, 0, 10, 11, 12,
- 69, 0, 13, 0, 38, 6, 14, 0, 15, 9,
- 0, 10, 11, 0, 38, 6, 39, 16, 0, 17,
- 0, 10, 15, 0, 0, 69, 39, 0, 0, 0,
- 0, 16, 15, 17, 0, 0, 0, 0, 0, 40,
- 0, 0, 0, 17, 0, 0, 0, 0, 0, 42
+ 50, 51, 7, 34, 112, 113, 7, 34, 16, 9,
+ 17, 10, 11, 12, 0, 0, 13, 18, 0, 19,
+ 14, 0, 15, 50, 51, 7, 34, 0, 67, 52,
+ 0, 16, 0, 114, 68, 69, 70, 71, 0, 72,
+ 73, 94, 19, 138, 0, 0, 146, 112, 113, 7,
+ 34, 0, 9, 0, 10, 11, 12, 0, 0, 13,
+ 0, 0, 0, 14, 94, 15, 0, 0, 0, 0,
+ 50, 51, 7, 34, 16, 0, 114, 68, 69, 70,
+ 71, 0, 72, 73, 0, 19, 86, 0, 115, 112,
+ 113, 7, 34, 0, 9, 0, 10, 11, 12, 52,
+ 0, 13, 0, 0, 67, 14, 0, 15, 0, 132,
+ 68, 69, 70, 71, 0, 72, 16, 0, 114, 86,
+ 0, 68, 69, 70, 71, 73, 72, 19, 138, 112,
+ 113, 7, 34, 0, 9, 0, 10, 11, 12, 0,
+ 0, 13, 0, 39, 6, 14, 0, 15, 9, 0,
+ 10, 11, 12, 0, 0, 13, 16, 0, 114, 14,
+ 0, 15, 0, 0, 0, 73, 0, 19, 39, 6,
+ 16, 0, 17, 9, 0, 10, 11, 12, 0, 18,
+ 13, 19, 39, 6, 14, 0, 15, 9, 0, 10,
+ 11, 0, 0, 0, 40, 16, 0, 17, 39, 6,
+ 15, 134, 135, 0, 73, 10, 19, 0, 10, 16,
+ 40, 17, 0, 40, 0, 0, 15, 0, 41, 15,
+ 62, 63, 0, 64, 65, 66, 0, 17, 62, 137,
+ 17, 64, 65, 66, 43, 0, 0, 43
};
-static const yytype_int8 yycheck[] =
+static const yytype_int16 yycheck[] =
{
- 17, 58, 16, 81, 1, 1, 20, 23, 54, 10,
- 96, 5, 98, 31, 32, 61, 62, 74, 10, 16,
- 17, 18, 18, 109, 42, 42, 42, 24, 24, 1,
- 116, 31, 32, 18, 31, 31, 114, 9, 35, 24,
- 118, 58, 59, 40, 27, 42, 63, 64, 65, 66,
- 67, 68, 40, 34, 35, 36, 37, 74, 39, 56,
- 57, 1, 6, 10, 8, 9, 63, 64, 65, 66,
- 67, 68, 69, 69, 36, 37, 16, 39, 18, 96,
- 5, 98, 25, 26, 24, 34, 35, 36, 37, 23,
- 39, 31, 109, 42, 39, 35, 28, 43, 115, 116,
- 40, 43, 34, 35, 36, 37, 43, 39, 6, 7,
- 42, 42, 28, 6, 7, 32, 56, 57, 34, 35,
- 36, 37, 12, 39, 0, 1, 12, 42, 4, 69,
- 6, 7, 8, 9, 10, 11, 43, 13, 14, 15,
- -1, -1, 18, -1, -1, -1, 22, -1, 24, 16,
- 17, -1, 19, 20, 21, -1, -1, 33, -1, 35,
- -1, 6, 7, 8, 9, 41, 11, -1, 13, 14,
+ 1, 17, 18, 23, 1, 18, 16, 99, 9, 90,
+ 20, 78, 25, 17, 31, 32, 32, 6, 7, 19,
+ 10, 18, 58, 43, 5, 41, 43, 43, 25, 65,
+ 66, 25, 26, 19, 125, 32, 10, 129, 41, 43,
+ 132, 6, 7, 8, 9, 136, 35, 138, 115, 27,
+ 131, 67, 68, 69, 70, 71, 72, 73, 125, 140,
+ 31, 32, 78, 67, 68, 69, 70, 71, 72, 136,
+ 35, 138, 36, 37, 78, 39, 73, 78, 78, 6,
+ 45, 8, 9, 48, 6, 7, 8, 9, 1, 10,
+ 90, 5, 78, 23, 6, 7, 39, 43, 114, 115,
+ 45, 32, 12, 16, 90, 18, 12, 12, 12, 125,
+ 114, 115, 25, 35, 115, 115, 45, 12, 12, 32,
+ 136, 125, 138, 36, 125, 125, 46, 115, 41, 115,
+ 130, 131, 136, 94, 138, 136, 136, 138, 138, 125,
+ 140, -1, -1, 62, 130, 131, -1, 60, 61, -1,
+ 136, -1, 138, -1, 140, 0, 1, -1, -1, 4,
+ 73, 6, 7, 8, 9, 10, 11, -1, 13, 14,
15, -1, -1, 18, -1, -1, -1, 22, -1, 24,
- 16, 17, -1, 19, 20, 21, -1, -1, 33, -1,
- 35, -1, 6, 7, 8, 9, 41, 11, 43, 13,
- 14, 15, -1, -1, 18, -1, 6, 7, 22, -1,
- 24, 11, -1, 13, 14, 15, -1, -1, 18, 33,
- -1, 35, 22, -1, 24, -1, -1, 41, -1, -1,
- -1, 6, 7, 33, -1, 35, 11, -1, 13, 14,
- 15, 41, -1, 18, -1, 6, 7, 22, -1, 24,
- 11, -1, 13, 14, 15, -1, -1, 18, 33, -1,
- 35, 22, -1, 24, -1, -1, 41, -1, -1, -1,
- 6, 7, 33, -1, 35, 11, -1, 13, 14, 15,
- 41, -1, 18, -1, 6, 7, 22, -1, 24, 11,
- -1, 13, 14, -1, 6, 7, 18, 33, -1, 35,
- -1, 13, 24, -1, -1, 41, 18, -1, -1, -1,
- -1, 33, 24, 35, -1, -1, -1, -1, -1, 41,
- -1, -1, -1, 35, -1, -1, -1, -1, -1, 41
+ 6, 7, 8, 9, 6, 7, 8, 9, 33, 11,
+ 35, 13, 14, 15, -1, -1, 18, 42, -1, 44,
+ 22, -1, 24, 6, 7, 8, 9, -1, 28, 35,
+ -1, 33, -1, 35, 34, 35, 36, 37, -1, 39,
+ 42, 47, 44, 45, -1, -1, 48, 6, 7, 8,
+ 9, -1, 11, -1, 13, 14, 15, -1, -1, 18,
+ -1, -1, -1, 22, 47, 24, -1, -1, -1, -1,
+ 6, 7, 8, 9, 33, -1, 35, 34, 35, 36,
+ 37, -1, 39, 42, -1, 44, 43, -1, 47, 6,
+ 7, 8, 9, -1, 11, -1, 13, 14, 15, 35,
+ -1, 18, -1, -1, 28, 22, -1, 24, -1, 45,
+ 34, 35, 36, 37, -1, 39, 33, -1, 35, 43,
+ -1, 34, 35, 36, 37, 42, 39, 44, 45, 6,
+ 7, 8, 9, -1, 11, -1, 13, 14, 15, -1,
+ -1, 18, -1, 6, 7, 22, -1, 24, 11, -1,
+ 13, 14, 15, -1, -1, 18, 33, -1, 35, 22,
+ -1, 24, -1, -1, -1, 42, -1, 44, 6, 7,
+ 33, -1, 35, 11, -1, 13, 14, 15, -1, 42,
+ 18, 44, 6, 7, 22, -1, 24, 11, -1, 13,
+ 14, -1, -1, -1, 18, 33, -1, 35, 6, 7,
+ 24, 6, 7, -1, 42, 13, 44, -1, 13, 33,
+ 18, 35, -1, 18, -1, -1, 24, -1, 42, 24,
+ 16, 17, -1, 19, 20, 21, -1, 35, 16, 17,
+ 35, 19, 20, 21, 42, -1, -1, 42
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */
static const yytype_uint8 yystos[] =
{
- 0, 45, 0, 1, 4, 6, 7, 8, 9, 11,
- 13, 14, 15, 18, 22, 24, 33, 35, 41, 46,
- 47, 48, 49, 50, 52, 53, 54, 55, 57, 10,
- 5, 40, 6, 9, 52, 27, 58, 59, 6, 18,
- 41, 53, 41, 54, 55, 6, 7, 50, 51, 53,
- 55, 57, 10, 5, 23, 50, 31, 32, 16, 17,
- 19, 20, 21, 28, 34, 35, 36, 37, 39, 41,
- 53, 55, 57, 53, 25, 26, 60, 53, 55, 16,
- 42, 43, 42, 42, 42, 58, 53, 53, 6, 7,
- 52, 53, 54, 55, 56, 57, 62, 63, 62, 58,
- 58, 55, 55, 55, 55, 55, 55, 57, 61, 62,
- 6, 7, 51, 12, 12, 17, 43, 63, 43, 6,
- 7, 51, 63, 51, 42
+ 0, 50, 0, 1, 4, 6, 7, 8, 9, 11,
+ 13, 14, 15, 18, 22, 24, 33, 35, 42, 44,
+ 51, 52, 53, 54, 55, 59, 60, 61, 62, 64,
+ 10, 5, 41, 6, 9, 59, 27, 65, 66, 6,
+ 18, 42, 60, 42, 61, 62, 55, 60, 62, 64,
+ 6, 7, 35, 56, 57, 58, 10, 5, 23, 55,
+ 31, 32, 16, 17, 19, 20, 21, 28, 34, 35,
+ 36, 37, 39, 42, 60, 62, 64, 60, 25, 26,
+ 67, 60, 62, 16, 43, 43, 43, 43, 6, 7,
+ 45, 65, 60, 60, 47, 56, 57, 59, 70, 71,
+ 73, 74, 70, 65, 65, 62, 62, 62, 62, 62,
+ 62, 64, 6, 7, 35, 47, 56, 57, 59, 60,
+ 61, 62, 63, 64, 68, 69, 72, 74, 58, 71,
+ 12, 12, 45, 73, 6, 7, 69, 17, 45, 72,
+ 45, 48, 56, 57, 58, 73, 48, 72, 58, 46
};
#define yyerrok (yyerrstatus = 0)
switch (yytype)
{
case 5: /* "HELP_TOPIC" */
-#line 158 "parser.y"
+#line 161 "parser.y"
{ free((yyvaluep->str)); };
-#line 1274 "parser.c"
+#line 1317 "parser.c"
break;
case 8: /* "STR" */
-#line 158 "parser.y"
+#line 161 "parser.y"
{ free((yyvaluep->str)); };
-#line 1279 "parser.c"
+#line 1322 "parser.c"
break;
case 9: /* "IDENTIFIER" */
-#line 158 "parser.y"
+#line 161 "parser.y"
{ free((yyvaluep->str)); };
-#line 1284 "parser.c"
+#line 1327 "parser.c"
break;
case 25: /* "PARAM" */
-#line 159 "parser.y"
+#line 162 "parser.y"
{ if((yyvaluep->str)) free((yyvaluep->str)); };
-#line 1289 "parser.c"
+#line 1332 "parser.c"
break;
case 28: /* "CMP_OP" */
-#line 158 "parser.y"
+#line 161 "parser.y"
{ free((yyvaluep->str)); };
-#line 1294 "parser.c"
+#line 1337 "parser.c"
break;
- case 46: /* "command" */
-#line 160 "parser.y"
+ case 51: /* "command" */
+#line 163 "parser.y"
{ if((yyvaluep->sel)) _gmx_selelem_free((yyvaluep->sel)); };
-#line 1299 "parser.c"
+#line 1342 "parser.c"
break;
- case 47: /* "cmd_plain" */
-#line 160 "parser.y"
+ case 52: /* "cmd_plain" */
+#line 163 "parser.y"
{ if((yyvaluep->sel)) _gmx_selelem_free((yyvaluep->sel)); };
-#line 1304 "parser.c"
+#line 1347 "parser.c"
break;
- case 50: /* "selection" */
-#line 161 "parser.y"
+ case 55: /* "selection" */
+#line 164 "parser.y"
{ _gmx_selelem_free_chain((yyvaluep->sel)); };
-#line 1309 "parser.c"
+#line 1352 "parser.c"
break;
- case 52: /* "string" */
-#line 158 "parser.y"
+ case 59: /* "string" */
+#line 161 "parser.y"
{ free((yyvaluep->str)); };
-#line 1314 "parser.c"
+#line 1357 "parser.c"
break;
- case 53: /* "sel_expr" */
-#line 162 "parser.y"
+ case 60: /* "sel_expr" */
+#line 165 "parser.y"
{ _gmx_selelem_free((yyvaluep->sel)); };
-#line 1319 "parser.c"
+#line 1362 "parser.c"
break;
- case 55: /* "num_expr" */
-#line 162 "parser.y"
+ case 62: /* "num_expr" */
+#line 165 "parser.y"
{ _gmx_selelem_free((yyvaluep->sel)); };
-#line 1324 "parser.c"
+#line 1367 "parser.c"
break;
- case 56: /* "str_expr" */
-#line 162 "parser.y"
+ case 63: /* "str_expr" */
+#line 165 "parser.y"
{ _gmx_selelem_free((yyvaluep->sel)); };
-#line 1329 "parser.c"
+#line 1372 "parser.c"
break;
- case 57: /* "pos_expr" */
-#line 162 "parser.y"
+ case 64: /* "pos_expr" */
+#line 165 "parser.y"
{ _gmx_selelem_free((yyvaluep->sel)); };
-#line 1334 "parser.c"
+#line 1377 "parser.c"
break;
- case 58: /* "method_params" */
-#line 163 "parser.y"
+ case 65: /* "method_params" */
+#line 166 "parser.y"
{ _gmx_selexpr_free_params((yyvaluep->param)); };
-#line 1339 "parser.c"
+#line 1382 "parser.c"
break;
- case 59: /* "method_param_list" */
-#line 163 "parser.y"
+ case 66: /* "method_param_list" */
+#line 166 "parser.y"
{ _gmx_selexpr_free_params((yyvaluep->param)); };
-#line 1344 "parser.c"
+#line 1387 "parser.c"
break;
- case 60: /* "method_param" */
-#line 163 "parser.y"
+ case 67: /* "method_param" */
+#line 166 "parser.y"
{ _gmx_selexpr_free_params((yyvaluep->param)); };
-#line 1349 "parser.c"
+#line 1392 "parser.c"
break;
- case 61: /* "value_list" */
-#line 164 "parser.y"
+ case 68: /* "value_list" */
+#line 167 "parser.y"
{ _gmx_selexpr_free_values((yyvaluep->val)); };
-#line 1354 "parser.c"
+#line 1397 "parser.c"
break;
- case 62: /* "value_list_nonempty" */
-#line 164 "parser.y"
+ case 69: /* "value_list_contents" */
+#line 167 "parser.y"
{ _gmx_selexpr_free_values((yyvaluep->val)); };
-#line 1359 "parser.c"
+#line 1402 "parser.c"
break;
- case 63: /* "value_item" */
-#line 164 "parser.y"
+ case 70: /* "basic_value_list" */
+#line 168 "parser.y"
+ { _gmx_selexpr_free_values((yyvaluep->val)); };
+#line 1407 "parser.c"
+ break;
+ case 71: /* "basic_value_list_contents" */
+#line 168 "parser.y"
+ { _gmx_selexpr_free_values((yyvaluep->val)); };
+#line 1412 "parser.c"
+ break;
+ case 72: /* "value_item" */
+#line 167 "parser.y"
+ { _gmx_selexpr_free_values((yyvaluep->val)); };
+#line 1417 "parser.c"
+ break;
+ case 73: /* "basic_value_item" */
+#line 168 "parser.y"
+ { _gmx_selexpr_free_values((yyvaluep->val)); };
+#line 1422 "parser.c"
+ break;
+ case 74: /* "value_item_range" */
+#line 167 "parser.y"
{ _gmx_selexpr_free_values((yyvaluep->val)); };
-#line 1364 "parser.c"
+#line 1427 "parser.c"
break;
default:
switch (yyn)
{
case 2:
-#line 178 "parser.y"
+#line 182 "parser.y"
{ (yyval.sel) = NULL ;}
break;
case 3:
-#line 180 "parser.y"
+#line 184 "parser.y"
{
(yyval.sel) = _gmx_sel_append_selection((yyvsp[(2) - (2)].sel), (yyvsp[(1) - (2)].sel), scanner);
if (_gmx_sel_parser_should_finish(scanner))
break;
case 4:
-#line 188 "parser.y"
+#line 192 "parser.y"
{ (yyval.sel) = (yyvsp[(1) - (2)].sel); ;}
break;
case 5:
-#line 190 "parser.y"
+#line 194 "parser.y"
{
(yyval.sel) = NULL;
_gmx_selparser_error("invalid selection '%s'",
break;
case 6:
-#line 209 "parser.y"
+#line 213 "parser.y"
{
(yyval.sel) = NULL;
_gmx_sel_handle_empty_cmd(scanner);
break;
case 7:
-#line 213 "parser.y"
+#line 217 "parser.y"
{ (yyval.sel) = NULL; ;}
break;
case 8:
-#line 215 "parser.y"
+#line 219 "parser.y"
{
t_selelem *s, *p;
s = _gmx_sel_init_group_by_id((yyvsp[(1) - (1)].i), scanner);
break;
case 9:
-#line 224 "parser.y"
+#line 228 "parser.y"
{
t_selelem *s, *p;
s = _gmx_sel_init_group_by_name((yyvsp[(1) - (1)].str), scanner);
break;
case 10:
-#line 234 "parser.y"
+#line 238 "parser.y"
{ (yyval.sel) = _gmx_sel_init_selection(NULL, (yyvsp[(1) - (1)].sel), scanner); ;}
break;
case 11:
-#line 236 "parser.y"
+#line 240 "parser.y"
{ (yyval.sel) = _gmx_sel_init_selection((yyvsp[(1) - (2)].str), (yyvsp[(2) - (2)].sel), scanner); ;}
break;
case 12:
-#line 238 "parser.y"
+#line 242 "parser.y"
{ (yyval.sel) = _gmx_sel_assign_variable((yyvsp[(1) - (3)].str), (yyvsp[(3) - (3)].sel), scanner); ;}
break;
case 13:
-#line 240 "parser.y"
+#line 244 "parser.y"
{ (yyval.sel) = _gmx_sel_assign_variable((yyvsp[(1) - (3)].str), (yyvsp[(3) - (3)].sel), scanner); ;}
break;
case 14:
-#line 242 "parser.y"
+#line 246 "parser.y"
{ (yyval.sel) = _gmx_sel_assign_variable((yyvsp[(1) - (3)].str), (yyvsp[(3) - (3)].sel), scanner); ;}
break;
case 15:
-#line 247 "parser.y"
+#line 251 "parser.y"
{ _gmx_sel_handle_help_cmd(NULL, scanner); ;}
break;
case 17:
-#line 251 "parser.y"
+#line 255 "parser.y"
{ _gmx_sel_handle_help_cmd((yyvsp[(2) - (2)].str), scanner); ;}
break;
case 18:
-#line 252 "parser.y"
+#line 256 "parser.y"
{ _gmx_sel_handle_help_cmd((yyvsp[(2) - (2)].str), scanner); ;}
break;
case 19:
-#line 256 "parser.y"
+#line 260 "parser.y"
{ (yyval.sel) = (yyvsp[(1) - (1)].sel); ;}
break;
case 20:
-#line 258 "parser.y"
+#line 262 "parser.y"
{
(yyval.sel) = _gmx_sel_init_position((yyvsp[(1) - (1)].sel), NULL, scanner);
if ((yyval.sel) == NULL) YYERROR;
break;
case 21:
-#line 262 "parser.y"
+#line 266 "parser.y"
{ (yyval.sel) = (yyvsp[(2) - (3)].sel); ;}
break;
case 22:
-#line 264 "parser.y"
+#line 268 "parser.y"
{
(yyval.sel) = _gmx_sel_init_modifier((yyvsp[(2) - (3)].meth), (yyvsp[(3) - (3)].param), (yyvsp[(1) - (3)].sel), scanner);
if ((yyval.sel) == NULL) YYERROR;
break;
case 23:
-#line 274 "parser.y"
+#line 279 "parser.y"
{ (yyval.r) = (yyvsp[(1) - (1)].i); ;}
break;
case 24:
-#line 275 "parser.y"
- { (yyval.r) = (yyvsp[(1) - (1)].r); ;}
+#line 280 "parser.y"
+ { (yyval.r) = -(yyvsp[(2) - (2)].i); ;}
break;
case 25:
-#line 278 "parser.y"
- { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
+#line 284 "parser.y"
+ { (yyval.r) = (yyvsp[(1) - (1)].r); ;}
break;
case 26:
-#line 279 "parser.y"
- { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
+#line 285 "parser.y"
+ { (yyval.r) = -(yyvsp[(2) - (2)].r); ;}
break;
case 27:
#line 288 "parser.y"
+ { (yyval.r) = (yyvsp[(1) - (1)].r); ;}
+ break;
+
+ case 28:
+#line 289 "parser.y"
+ { (yyval.r) = (yyvsp[(1) - (1)].r); ;}
+ break;
+
+ case 29:
+#line 292 "parser.y"
+ { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
+ break;
+
+ case 30:
+#line 293 "parser.y"
+ { (yyval.str) = (yyvsp[(1) - (1)].str); ;}
+ break;
+
+ case 31:
+#line 302 "parser.y"
{
(yyval.sel) = _gmx_selelem_create(SEL_BOOLEAN);
(yyval.sel)->u.boolt = BOOL_NOT;
;}
break;
- case 28:
-#line 294 "parser.y"
+ case 32:
+#line 308 "parser.y"
{
(yyval.sel) = _gmx_selelem_create(SEL_BOOLEAN);
(yyval.sel)->u.boolt = BOOL_AND;
;}
break;
- case 29:
-#line 300 "parser.y"
+ case 33:
+#line 314 "parser.y"
{
(yyval.sel) = _gmx_selelem_create(SEL_BOOLEAN);
(yyval.sel)->u.boolt = BOOL_OR;
;}
break;
- case 30:
-#line 311 "parser.y"
+ case 34:
+#line 325 "parser.y"
{ (yyval.sel) = (yyvsp[(2) - (3)].sel); ;}
break;
- case 31:
-#line 316 "parser.y"
+ case 35:
+#line 330 "parser.y"
{
(yyval.sel) = _gmx_sel_init_comparison((yyvsp[(1) - (3)].sel), (yyvsp[(3) - (3)].sel), (yyvsp[(2) - (3)].str), scanner);
if ((yyval.sel) == NULL) YYERROR;
;}
break;
- case 32:
-#line 324 "parser.y"
+ case 36:
+#line 338 "parser.y"
{
(yyval.sel) = _gmx_sel_init_group_by_name((yyvsp[(2) - (2)].str), scanner);
free((yyvsp[(2) - (2)].str));
;}
break;
- case 33:
-#line 330 "parser.y"
+ case 37:
+#line 344 "parser.y"
{
(yyval.sel) = _gmx_sel_init_group_by_id((yyvsp[(2) - (2)].i), scanner);
if ((yyval.sel) == NULL) YYERROR;
;}
break;
- case 34:
-#line 337 "parser.y"
+ case 38:
+#line 351 "parser.y"
{ (yyval.str) = NULL; ;}
break;
- case 35:
-#line 338 "parser.y"
+ case 39:
+#line 352 "parser.y"
{ (yyval.str) = (yyvsp[(1) - (1)].str); ;}
break;
- case 36:
-#line 343 "parser.y"
+ case 40:
+#line 357 "parser.y"
{
(yyval.sel) = _gmx_sel_init_keyword((yyvsp[(2) - (2)].meth), NULL, (yyvsp[(1) - (2)].str), scanner);
if ((yyval.sel) == NULL) YYERROR;
;}
break;
- case 37:
-#line 348 "parser.y"
+ case 41:
+#line 362 "parser.y"
{
(yyval.sel) = _gmx_sel_init_keyword((yyvsp[(2) - (3)].meth), process_value_list((yyvsp[(3) - (3)].val), NULL), (yyvsp[(1) - (3)].str), scanner);
if ((yyval.sel) == NULL) YYERROR;
;}
break;
- case 38:
-#line 353 "parser.y"
+ case 42:
+#line 367 "parser.y"
{
(yyval.sel) = _gmx_sel_init_keyword((yyvsp[(2) - (3)].meth), process_value_list((yyvsp[(3) - (3)].val), NULL), (yyvsp[(1) - (3)].str), scanner);
if ((yyval.sel) == NULL) YYERROR;
;}
break;
- case 39:
-#line 361 "parser.y"
+ case 43:
+#line 375 "parser.y"
{
(yyval.sel) = _gmx_sel_init_method((yyvsp[(2) - (3)].meth), (yyvsp[(3) - (3)].param), (yyvsp[(1) - (3)].str), scanner);
if ((yyval.sel) == NULL) YYERROR;
;}
break;
- case 40:
-#line 373 "parser.y"
+ case 44:
+#line 387 "parser.y"
{
(yyval.sel) = _gmx_selelem_create(SEL_CONST);
_gmx_selelem_set_vtype((yyval.sel), INT_VALUE);
;}
break;
- case 41:
-#line 380 "parser.y"
+ case 45:
+#line 394 "parser.y"
{
(yyval.sel) = _gmx_selelem_create(SEL_CONST);
_gmx_selelem_set_vtype((yyval.sel), REAL_VALUE);
;}
break;
- case 42:
-#line 390 "parser.y"
+ case 46:
+#line 404 "parser.y"
{
(yyval.sel) = _gmx_sel_init_keyword((yyvsp[(2) - (2)].meth), NULL, (yyvsp[(1) - (2)].str), scanner);
if ((yyval.sel) == NULL) YYERROR;
;}
break;
- case 43:
-#line 395 "parser.y"
+ case 47:
+#line 409 "parser.y"
{
(yyval.sel) = _gmx_sel_init_method((yyvsp[(2) - (3)].meth), (yyvsp[(3) - (3)].param), (yyvsp[(1) - (3)].str), scanner);
if ((yyval.sel) == NULL) YYERROR;
;}
break;
- case 44:
-#line 403 "parser.y"
+ case 48:
+#line 417 "parser.y"
{ (yyval.sel) = _gmx_sel_init_arithmetic((yyvsp[(1) - (3)].sel), (yyvsp[(3) - (3)].sel), '+', scanner); ;}
break;
- case 45:
-#line 405 "parser.y"
+ case 49:
+#line 419 "parser.y"
{ (yyval.sel) = _gmx_sel_init_arithmetic((yyvsp[(1) - (3)].sel), (yyvsp[(3) - (3)].sel), '-', scanner); ;}
break;
- case 46:
-#line 407 "parser.y"
+ case 50:
+#line 421 "parser.y"
{ (yyval.sel) = _gmx_sel_init_arithmetic((yyvsp[(1) - (3)].sel), (yyvsp[(3) - (3)].sel), '*', scanner); ;}
break;
- case 47:
-#line 409 "parser.y"
+ case 51:
+#line 423 "parser.y"
{ (yyval.sel) = _gmx_sel_init_arithmetic((yyvsp[(1) - (3)].sel), (yyvsp[(3) - (3)].sel), '/', scanner); ;}
break;
- case 48:
-#line 411 "parser.y"
+ case 52:
+#line 425 "parser.y"
{ (yyval.sel) = _gmx_sel_init_arithmetic((yyvsp[(2) - (2)].sel), NULL, '-', scanner); ;}
break;
- case 49:
-#line 413 "parser.y"
+ case 53:
+#line 427 "parser.y"
{ (yyval.sel) = _gmx_sel_init_arithmetic((yyvsp[(1) - (3)].sel), (yyvsp[(3) - (3)].sel), '^', scanner); ;}
break;
- case 50:
-#line 414 "parser.y"
+ case 54:
+#line 428 "parser.y"
{ (yyval.sel) = (yyvsp[(2) - (3)].sel); ;}
break;
- case 51:
-#line 422 "parser.y"
+ case 55:
+#line 436 "parser.y"
{
(yyval.sel) = _gmx_selelem_create(SEL_CONST);
_gmx_selelem_set_vtype((yyval.sel), STR_VALUE);
;}
break;
- case 52:
-#line 429 "parser.y"
+ case 56:
+#line 443 "parser.y"
{
(yyval.sel) = _gmx_sel_init_keyword((yyvsp[(2) - (2)].meth), NULL, (yyvsp[(1) - (2)].str), scanner);
if ((yyval.sel) == NULL) YYERROR;
;}
break;
- case 53:
-#line 441 "parser.y"
+ case 57:
+#line 455 "parser.y"
{ (yyval.sel) = _gmx_sel_init_const_position((yyvsp[(2) - (7)].r), (yyvsp[(4) - (7)].r), (yyvsp[(6) - (7)].r)); ;}
break;
- case 54:
-#line 445 "parser.y"
+ case 58:
+#line 459 "parser.y"
{ (yyval.sel) = (yyvsp[(2) - (3)].sel); ;}
break;
- case 55:
-#line 450 "parser.y"
+ case 59:
+#line 464 "parser.y"
{
(yyval.sel) = _gmx_sel_init_method((yyvsp[(1) - (2)].meth), (yyvsp[(2) - (2)].param), NULL, scanner);
if ((yyval.sel) == NULL) YYERROR;
;}
break;
- case 56:
-#line 458 "parser.y"
+ case 60:
+#line 472 "parser.y"
{
(yyval.sel) = _gmx_sel_init_position((yyvsp[(3) - (3)].sel), (yyvsp[(1) - (3)].str), scanner);
if ((yyval.sel) == NULL) YYERROR;
;}
break;
- case 57:
-#line 469 "parser.y"
+ case 61:
+#line 483 "parser.y"
{ (yyval.sel) = _gmx_sel_init_variable_ref((yyvsp[(1) - (1)].sel)); ;}
break;
- case 58:
-#line 473 "parser.y"
+ case 62:
+#line 487 "parser.y"
{ (yyval.sel) = _gmx_sel_init_variable_ref((yyvsp[(1) - (1)].sel)); ;}
break;
- case 59:
-#line 477 "parser.y"
+ case 63:
+#line 491 "parser.y"
{ (yyval.sel) = _gmx_sel_init_variable_ref((yyvsp[(1) - (1)].sel)); ;}
break;
- case 60:
-#line 486 "parser.y"
+ case 64:
+#line 500 "parser.y"
{ (yyval.param) = process_param_list((yyvsp[(1) - (1)].param)); ;}
break;
- case 61:
-#line 488 "parser.y"
+ case 65:
+#line 502 "parser.y"
{ (yyval.param) = process_param_list((yyvsp[(1) - (2)].param)); ;}
break;
- case 62:
-#line 492 "parser.y"
+ case 66:
+#line 506 "parser.y"
{ (yyval.param) = NULL; ;}
break;
- case 63:
-#line 494 "parser.y"
+ case 67:
+#line 508 "parser.y"
{ (yyvsp[(2) - (2)].param)->next = (yyvsp[(1) - (2)].param); (yyval.param) = (yyvsp[(2) - (2)].param); ;}
break;
- case 64:
-#line 499 "parser.y"
+ case 68:
+#line 513 "parser.y"
{
(yyval.param) = _gmx_selexpr_create_param((yyvsp[(1) - (2)].str));
(yyval.param)->value = process_value_list((yyvsp[(2) - (2)].val), &(yyval.param)->nval);
;}
break;
- case 65:
-#line 505 "parser.y"
+ case 69:
+#line 519 "parser.y"
{ (yyval.val) = NULL; ;}
break;
- case 66:
-#line 506 "parser.y"
+ case 70:
+#line 520 "parser.y"
{ (yyval.val) = (yyvsp[(1) - (1)].val); ;}
break;
- case 67:
-#line 510 "parser.y"
+ case 71:
+#line 521 "parser.y"
+ { (yyval.val) = (yyvsp[(2) - (3)].val); ;}
+ break;
+
+ case 72:
+#line 525 "parser.y"
{ (yyval.val) = (yyvsp[(1) - (1)].val); ;}
break;
- case 68:
-#line 512 "parser.y"
+ case 73:
+#line 527 "parser.y"
{ (yyvsp[(2) - (2)].val)->next = (yyvsp[(1) - (2)].val); (yyval.val) = (yyvsp[(2) - (2)].val); ;}
break;
- case 69:
-#line 514 "parser.y"
+ case 74:
+#line 529 "parser.y"
{ (yyvsp[(3) - (3)].val)->next = (yyvsp[(1) - (3)].val); (yyval.val) = (yyvsp[(3) - (3)].val); ;}
break;
- case 70:
-#line 518 "parser.y"
+ case 75:
+#line 533 "parser.y"
+ { (yyval.val) = (yyvsp[(1) - (1)].val); ;}
+ break;
+
+ case 76:
+#line 534 "parser.y"
+ { (yyval.val) = (yyvsp[(2) - (3)].val); ;}
+ break;
+
+ case 77:
+#line 538 "parser.y"
+ { (yyval.val) = (yyvsp[(1) - (1)].val); ;}
+ break;
+
+ case 78:
+#line 540 "parser.y"
+ { (yyvsp[(2) - (2)].val)->next = (yyvsp[(1) - (2)].val); (yyval.val) = (yyvsp[(2) - (2)].val); ;}
+ break;
+
+ case 79:
+#line 542 "parser.y"
+ { (yyvsp[(3) - (3)].val)->next = (yyvsp[(1) - (3)].val); (yyval.val) = (yyvsp[(3) - (3)].val); ;}
+ break;
+
+ case 80:
+#line 546 "parser.y"
{ (yyval.val) = _gmx_selexpr_create_value_expr((yyvsp[(1) - (1)].sel)); ;}
break;
- case 71:
-#line 520 "parser.y"
+ case 81:
+#line 548 "parser.y"
{ (yyval.val) = _gmx_selexpr_create_value_expr((yyvsp[(1) - (1)].sel)); ;}
break;
- case 72:
-#line 522 "parser.y"
+ case 82:
+#line 550 "parser.y"
{ (yyval.val) = _gmx_selexpr_create_value_expr((yyvsp[(1) - (1)].sel)); ;}
break;
- case 73:
-#line 524 "parser.y"
+ case 83:
+#line 552 "parser.y"
{ (yyval.val) = _gmx_selexpr_create_value_expr((yyvsp[(1) - (1)].sel)); ;}
break;
- case 74:
-#line 526 "parser.y"
+ case 84:
+#line 553 "parser.y"
+ { (yyval.val) = (yyvsp[(1) - (1)].val); ;}
+ break;
+
+ case 85:
+#line 558 "parser.y"
{
(yyval.val) = _gmx_selexpr_create_value(INT_VALUE);
- (yyval.val)->u.i.i1 = (yyvsp[(1) - (3)].i); (yyval.val)->u.i.i2 = (yyvsp[(3) - (3)].i);
+ (yyval.val)->u.i.i1 = (yyval.val)->u.i.i2 = (yyvsp[(1) - (1)].r);
;}
break;
- case 75:
-#line 531 "parser.y"
+ case 86:
+#line 563 "parser.y"
{
(yyval.val) = _gmx_selexpr_create_value(REAL_VALUE);
- (yyval.val)->u.r.r1 = (yyvsp[(1) - (3)].i); (yyval.val)->u.r.r2 = (yyvsp[(3) - (3)].r);
+ (yyval.val)->u.r.r1 = (yyval.val)->u.r.r2 = (yyvsp[(1) - (1)].r);
;}
break;
- case 76:
-#line 536 "parser.y"
+ case 87:
+#line 568 "parser.y"
+ {
+ (yyval.val) = _gmx_selexpr_create_value(STR_VALUE);
+ (yyval.val)->u.s = (yyvsp[(1) - (1)].str);
+ ;}
+ break;
+
+ case 88:
+#line 572 "parser.y"
+ { (yyval.val) = (yyvsp[(1) - (1)].val); ;}
+ break;
+
+ case 89:
+#line 577 "parser.y"
+ {
+ (yyval.val) = _gmx_selexpr_create_value(INT_VALUE);
+ (yyval.val)->u.i.i1 = (yyvsp[(1) - (3)].r); (yyval.val)->u.i.i2 = (yyvsp[(3) - (3)].r);
+ ;}
+ break;
+
+ case 90:
+#line 582 "parser.y"
+ {
+ (yyval.val) = _gmx_selexpr_create_value(REAL_VALUE);
+ (yyval.val)->u.r.r1 = (yyvsp[(1) - (3)].r); (yyval.val)->u.r.r2 = (yyvsp[(3) - (3)].r);
+ ;}
+ break;
+
+ case 91:
+#line 587 "parser.y"
{
(yyval.val) = _gmx_selexpr_create_value(REAL_VALUE);
(yyval.val)->u.r.r1 = (yyvsp[(1) - (3)].r); (yyval.val)->u.r.r2 = (yyvsp[(3) - (3)].r);
/* Line 1267 of yacc.c. */
-#line 2162 "parser.c"
+#line 2309 "parser.c"
default: break;
}
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
}
-#line 542 "parser.y"
+#line 593 "parser.y"
static t_selexpr_value *
OR = 286,
AND = 287,
NOT = 288,
- UNARY_NEG = 289
+ UNARY_NEG = 289,
+ NUM_REDUCT = 290
};
#endif
/* Tokens. */
#define AND 287
#define NOT 288
#define UNARY_NEG 289
+#define NUM_REDUCT 290
struct t_selexpr_param *param;
}
/* Line 1489 of yacc.c. */
-#line 129 "parser.h"
+#line 131 "parser.h"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
%left '*' '/'
%right UNARY_NEG /* Dummy token for unary negation precedence */
%right '^'
+%nonassoc NUM_REDUCT /* Dummy token for numerical keyword reduction precedence */
/* Simple non-terminals */
-%type <r> number
+%type <r> integer_number
+%type <r> real_number number
%type <str> string
%type <str> pos_mod
/* Parameter/value non-terminals */
%type <param> method_params method_param_list method_param
-%type <val> value_list value_list_nonempty value_item
+%type <val> value_list value_list_contents value_item value_item_range
+%type <val> basic_value_list basic_value_list_contents basic_value_item
%destructor { free($$); } HELP_TOPIC STR IDENTIFIER CMP_OP string
%destructor { if($$) free($$); } PARAM
%destructor { _gmx_selelem_free_chain($$); } selection
%destructor { _gmx_selelem_free($$); } sel_expr num_expr str_expr pos_expr
%destructor { _gmx_selexpr_free_params($$); } method_params method_param_list method_param
-%destructor { _gmx_selexpr_free_values($$); } value_list value_list_nonempty value_item
+%destructor { _gmx_selexpr_free_values($$); } value_list value_list_contents value_item value_item_range
+%destructor { _gmx_selexpr_free_values($$); } basic_value_list basic_value_list_contents basic_value_item
-%expect 91
+%expect 50
%debug
%pure-parser
* BASIC NON-TERMINAL SYMBOLS
********************************************************************/
-number: TOK_INT { $$ = $1; }
- | TOK_REAL { $$ = $1; }
+integer_number:
+ TOK_INT { $$ = $1; }
+ | '-' TOK_INT { $$ = -$2; }
+;
+
+real_number:
+ TOK_REAL { $$ = $1; }
+ | '-' TOK_REAL { $$ = -$2; }
+;
+
+number: integer_number { $$ = $1; }
+ | real_number { $$ = $1; }
;
string: STR { $$ = $1; }
$$ = _gmx_sel_init_keyword($2, NULL, $1, scanner);
if ($$ == NULL) YYERROR;
}
- | pos_mod KEYWORD_STR value_list_nonempty
+ | pos_mod KEYWORD_STR basic_value_list
{
$$ = _gmx_sel_init_keyword($2, process_value_list($3, NULL), $1, scanner);
if ($$ == NULL) YYERROR;
}
- | pos_mod KEYWORD_NUMERIC value_list_nonempty
+ | pos_mod KEYWORD_NUMERIC basic_value_list
{
$$ = _gmx_sel_init_keyword($2, process_value_list($3, NULL), $1, scanner);
if ($$ == NULL) YYERROR;
;
/* Numeric selection methods */
-num_expr: pos_mod KEYWORD_NUMERIC
+num_expr: pos_mod KEYWORD_NUMERIC %prec NUM_REDUCT
{
$$ = _gmx_sel_init_keyword($2, NULL, $1, scanner);
if ($$ == NULL) YYERROR;
********************************************************************/
/* Constant position expressions */
-pos_expr: '(' number ',' number ',' number ')'
+pos_expr: '[' number ',' number ',' number ']'
{ $$ = _gmx_sel_init_const_position($2, $4, $6); }
;
}
;
-value_list: /* empty */ { $$ = NULL; }
- | value_list_nonempty { $$ = $1; }
+value_list: /* empty */ { $$ = NULL; }
+ | value_list_contents { $$ = $1; }
+ | '{' value_list_contents '}' { $$ = $2; }
;
-value_list_nonempty:
+value_list_contents:
value_item { $$ = $1; }
- | value_list_nonempty value_item
+ | value_list_contents value_item
{ $2->next = $1; $$ = $2; }
- | value_list_nonempty ',' value_item
+ | value_list_contents ',' value_item
+ { $3->next = $1; $$ = $3; }
+;
+
+basic_value_list:
+ basic_value_list_contents { $$ = $1; }
+ | '{' basic_value_list_contents '}' { $$ = $2; }
+;
+
+basic_value_list_contents:
+ basic_value_item { $$ = $1; }
+ | basic_value_list_contents basic_value_item
+ { $2->next = $1; $$ = $2; }
+ | basic_value_list_contents ',' basic_value_item
{ $3->next = $1; $$ = $3; }
;
{ $$ = _gmx_selexpr_create_value_expr($1); }
| str_expr %prec PARAM_REDUCT
{ $$ = _gmx_selexpr_create_value_expr($1); }
- | TOK_INT TO TOK_INT
+ | value_item_range { $$ = $1; }
+;
+
+basic_value_item:
+ integer_number %prec PARAM_REDUCT
+ {
+ $$ = _gmx_selexpr_create_value(INT_VALUE);
+ $$->u.i.i1 = $$->u.i.i2 = $1;
+ }
+ | real_number %prec PARAM_REDUCT
+ {
+ $$ = _gmx_selexpr_create_value(REAL_VALUE);
+ $$->u.r.r1 = $$->u.r.r2 = $1;
+ }
+ | string %prec PARAM_REDUCT
+ {
+ $$ = _gmx_selexpr_create_value(STR_VALUE);
+ $$->u.s = $1;
+ }
+ | value_item_range { $$ = $1; }
+;
+
+value_item_range:
+ integer_number TO integer_number
{
$$ = _gmx_selexpr_create_value(INT_VALUE);
$$->u.i.i1 = $1; $$->u.i.i2 = $3;
}
- | TOK_INT TO TOK_REAL
+ | integer_number TO real_number
{
$$ = _gmx_selexpr_create_value(REAL_VALUE);
$$->u.r.r1 = $1; $$->u.r.r2 = $3;
}
- | TOK_REAL TO number
+ | real_number TO number
{
$$ = _gmx_selexpr_create_value(REAL_VALUE);
$$->u.r.r1 = $1; $$->u.r.r2 = $3;
flex_int32_t yy_verify;
flex_int32_t yy_nxt;
};
-static yyconst flex_int16_t yy_accept[93] =
+static yyconst flex_int16_t yy_accept[89] =
{ 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 27, 25, 23, 6, 20, 25, 1, 25, 25, 25,
- 2, 6, 21, 25, 22, 25, 24, 22, 22, 22,
- 22, 22, 22, 25, 22, 22, 22, 22, 22, 11,
- 8, 10, 10, 9, 23, 21, 0, 4, 0, 1,
- 17, 0, 0, 3, 3, 2, 24, 24, 22, 5,
- 22, 22, 22, 18, 15, 22, 18, 16, 13, 22,
- 12, 22, 22, 8, 9, 0, 0, 0, 3, 17,
- 22, 20, 19, 13, 22, 3, 0, 3, 22, 7,
- 14, 0
-
+ 27, 25, 23, 6, 20, 25, 1, 25, 25, 2,
+ 6, 21, 25, 22, 25, 24, 22, 22, 22, 22,
+ 22, 22, 25, 22, 22, 22, 22, 22, 11, 8,
+ 10, 10, 9, 23, 21, 0, 4, 0, 1, 17,
+ 3, 3, 2, 24, 24, 22, 5, 22, 22, 22,
+ 18, 15, 22, 18, 16, 13, 22, 12, 22, 22,
+ 8, 9, 0, 0, 3, 17, 22, 20, 19, 13,
+ 22, 0, 3, 3, 22, 7, 14, 0
} ;
static yyconst flex_int32_t yy_ec[256] =
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 2, 4, 5, 6, 1, 1, 7, 1, 1,
- 1, 1, 8, 1, 9, 10, 1, 11, 11, 11,
- 11, 11, 11, 11, 11, 11, 11, 1, 12, 13,
- 14, 13, 1, 1, 15, 15, 15, 15, 16, 15,
- 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
- 1, 17, 1, 1, 18, 1, 19, 15, 15, 20,
-
- 21, 22, 23, 24, 15, 15, 15, 25, 15, 26,
- 27, 28, 15, 29, 30, 31, 32, 15, 15, 33,
- 34, 15, 1, 35, 1, 1, 1, 1, 1, 1,
+ 1, 1, 8, 1, 8, 9, 1, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 1, 11, 12,
+ 13, 12, 1, 1, 14, 14, 14, 14, 15, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 1, 16, 1, 1, 17, 1, 18, 14, 14, 19,
+
+ 20, 21, 22, 23, 14, 14, 14, 24, 14, 25,
+ 26, 27, 14, 28, 29, 30, 31, 14, 14, 32,
+ 33, 14, 1, 34, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1
} ;
-static yyconst flex_int32_t yy_meta[36] =
+static yyconst flex_int32_t yy_meta[35] =
{ 0,
- 1, 1, 2, 1, 1, 1, 1, 1, 1, 3,
- 4, 1, 1, 1, 4, 4, 1, 4, 4, 4,
+ 1, 1, 2, 1, 1, 1, 1, 1, 3, 4,
+ 1, 1, 1, 4, 4, 1, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 1
+ 4, 4, 4, 1
} ;
-static yyconst flex_int16_t yy_base[98] =
+static yyconst flex_int16_t yy_base[94] =
{ 0,
- 0, 0, 144, 143, 10, 12, 145, 144, 46, 0,
- 167, 172, 164, 172, 151, 77, 0, 157, 30, 152,
- 74, 172, 148, 147, 0, 157, 149, 132, 128, 129,
- 126, 127, 126, 117, 64, 124, 70, 129, 128, 172,
- 146, 172, 172, 0, 145, 172, 83, 172, 141, 0,
- 172, 134, 87, 90, 91, 94, 134, 108, 0, 172,
- 123, 115, 110, 0, 0, 111, 172, 0, 108, 116,
- 0, 107, 111, 133, 0, 34, 112, 123, 103, 0,
- 97, 0, 0, 0, 97, 111, 98, 80, 61, 0,
- 0, 172, 123, 127, 129, 83, 79
+ 0, 0, 131, 130, 10, 12, 132, 131, 45, 0,
+ 153, 158, 150, 158, 138, 75, 0, 143, 139, 72,
+ 158, 135, 134, 0, 143, 136, 119, 115, 116, 113,
+ 114, 113, 104, 62, 111, 68, 116, 115, 158, 132,
+ 158, 158, 0, 131, 158, 79, 158, 127, 0, 158,
+ 84, 87, 91, 122, 31, 0, 158, 111, 103, 98,
+ 0, 0, 99, 158, 0, 96, 104, 0, 95, 99,
+ 120, 0, 34, 107, 76, 0, 82, 0, 0, 0,
+ 83, 99, 98, 95, 76, 0, 0, 158, 111, 115,
+ 117, 94, 84
} ;
-static yyconst flex_int16_t yy_def[98] =
+static yyconst flex_int16_t yy_def[94] =
{ 0,
- 92, 1, 1, 1, 1, 1, 1, 1, 92, 9,
- 92, 92, 92, 92, 92, 93, 94, 92, 92, 92,
- 95, 92, 92, 92, 96, 92, 95, 96, 96, 96,
- 96, 96, 96, 92, 96, 96, 96, 96, 96, 92,
- 92, 92, 92, 97, 92, 92, 93, 92, 92, 94,
- 92, 92, 92, 92, 92, 95, 95, 95, 96, 92,
- 96, 96, 96, 96, 96, 96, 92, 96, 96, 96,
- 96, 96, 96, 92, 97, 92, 92, 92, 95, 96,
- 96, 96, 96, 96, 96, 92, 92, 92, 96, 96,
- 96, 0, 92, 92, 92, 92, 92
+ 88, 1, 1, 1, 1, 1, 1, 1, 88, 9,
+ 88, 88, 88, 88, 88, 89, 90, 88, 88, 91,
+ 88, 88, 88, 92, 88, 91, 92, 92, 92, 92,
+ 92, 92, 88, 92, 92, 92, 92, 92, 88, 88,
+ 88, 88, 93, 88, 88, 89, 88, 88, 90, 88,
+ 88, 88, 91, 91, 91, 92, 88, 92, 92, 92,
+ 92, 92, 92, 88, 92, 92, 92, 92, 92, 92,
+ 88, 93, 88, 88, 91, 92, 92, 92, 92, 92,
+ 92, 88, 88, 88, 92, 92, 92, 0, 88, 88,
+ 88, 88, 88
} ;
-static yyconst flex_int16_t yy_nxt[208] =
+static yyconst flex_int16_t yy_nxt[193] =
{ 0,
12, 13, 14, 15, 16, 17, 18, 12, 19, 20,
- 21, 22, 23, 24, 25, 25, 26, 27, 28, 25,
- 25, 25, 29, 25, 25, 30, 31, 25, 25, 25,
- 32, 25, 33, 25, 34, 36, 37, 36, 37, 52,
- 53, 78, 78, 38, 86, 38, 40, 41, 42, 40,
- 40, 40, 40, 40, 40, 40, 40, 43, 40, 40,
- 44, 44, 40, 40, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
- 40, 48, 75, 55, 56, 68, 59, 48, 91, 58,
- 88, 70, 64, 49, 58, 71, 55, 53, 64, 49,
-
- 54, 54, 76, 55, 56, 77, 77, 76, 88, 58,
- 77, 77, 92, 79, 58, 78, 78, 92, 79, 87,
- 87, 86, 88, 47, 90, 47, 47, 50, 89, 50,
- 50, 57, 57, 86, 74, 85, 71, 84, 82, 83,
- 82, 81, 80, 92, 54, 47, 45, 74, 73, 72,
- 69, 67, 66, 65, 64, 63, 62, 61, 92, 60,
- 46, 46, 54, 51, 46, 45, 92, 39, 39, 35,
- 35, 11, 92, 92, 92, 92, 92, 92, 92, 92,
- 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
- 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
-
- 92, 92, 92, 92, 92, 92, 92
+ 21, 22, 23, 24, 24, 25, 26, 27, 24, 24,
+ 24, 28, 24, 24, 29, 30, 24, 24, 24, 31,
+ 24, 32, 24, 33, 35, 36, 35, 36, 74, 88,
+ 75, 82, 37, 83, 37, 39, 40, 41, 39, 39,
+ 39, 39, 39, 39, 39, 42, 39, 39, 43, 43,
+ 39, 39, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 43, 39, 47,
+ 52, 53, 65, 47, 88, 75, 55, 72, 67, 61,
+ 48, 55, 68, 51, 48, 61, 51, 56, 73, 52,
+
+ 53, 73, 87, 73, 84, 55, 73, 83, 83, 86,
+ 55, 46, 85, 46, 46, 49, 84, 49, 49, 54,
+ 54, 71, 81, 68, 80, 78, 79, 78, 77, 76,
+ 88, 46, 44, 71, 70, 69, 66, 64, 63, 62,
+ 61, 60, 59, 58, 88, 57, 45, 45, 51, 50,
+ 45, 44, 88, 38, 38, 34, 34, 11, 88, 88,
+ 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+ 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+ 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+ 88, 88
+
} ;
-static yyconst flex_int16_t yy_chk[208] =
+static yyconst flex_int16_t yy_chk[193] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 5, 5, 6, 6, 19,
- 19, 76, 76, 5, 76, 6, 9, 9, 9, 9,
+ 1, 1, 1, 1, 5, 5, 6, 6, 55, 55,
+ 55, 73, 5, 73, 6, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 16, 97, 21, 21, 35, 96, 47, 89, 21,
- 88, 37, 35, 16, 21, 37, 53, 53, 37, 47,
-
- 54, 55, 53, 56, 56, 54, 55, 53, 87, 56,
- 54, 55, 79, 79, 56, 58, 58, 58, 58, 77,
- 77, 86, 77, 93, 85, 93, 93, 94, 81, 94,
- 94, 95, 95, 78, 74, 73, 72, 70, 69, 66,
- 63, 62, 61, 57, 52, 49, 45, 41, 39, 38,
- 36, 34, 33, 32, 31, 30, 29, 28, 27, 26,
- 24, 23, 20, 18, 15, 13, 11, 8, 7, 4,
- 3, 92, 92, 92, 92, 92, 92, 92, 92, 92,
- 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
- 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
-
- 92, 92, 92, 92, 92, 92, 92
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 16,
+ 20, 20, 34, 46, 75, 75, 20, 93, 36, 34,
+ 16, 20, 36, 51, 46, 36, 52, 92, 51, 53,
+
+ 53, 52, 85, 51, 84, 53, 52, 83, 82, 81,
+ 53, 89, 77, 89, 89, 90, 74, 90, 90, 91,
+ 91, 71, 70, 69, 67, 66, 63, 60, 59, 58,
+ 54, 48, 44, 40, 38, 37, 35, 33, 32, 31,
+ 30, 29, 28, 27, 26, 25, 23, 22, 19, 18,
+ 15, 13, 11, 8, 7, 4, 3, 88, 88, 88,
+ 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+ 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+ 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+ 88, 88
+
} ;
/* The intent behind this definition is that it'll catch
-#line 575 "scanner.c"
+#line 571 "scanner.c"
#define INITIAL 0
#define matchof 1
}
-#line 838 "scanner.c"
+#line 834 "scanner.c"
if ( !yyg->yy_init )
{
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 93 )
+ if ( yy_current_state >= 89 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
++yy_cp;
}
- while ( yy_current_state != 92 );
+ while ( yy_current_state != 88 );
yy_cp = yyg->yy_last_accepting_cpos;
yy_current_state = yyg->yy_last_accepting_state;
#line 156 "scanner.l"
YY_FATAL_ERROR( "flex scanner jammed" );
YY_BREAK
-#line 1064 "scanner.c"
+#line 1060 "scanner.c"
case YY_STATE_EOF(INITIAL):
case YY_STATE_EOF(matchof):
case YY_STATE_EOF(matchbool):
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 93 )
+ if ( yy_current_state >= 89 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 93 )
+ if ( yy_current_state >= 89 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- yy_is_jam = (yy_current_state == 92);
+ yy_is_jam = (yy_current_state == 88);
return yy_is_jam ? 0 : yy_current_state;
}
DSEQ ([[:digit:]]+)
FRAC (([[:digit:]]*"."{DSEQ})|{DSEQ}".")
EXP ([eE][+-]?{DSEQ})
-REAL ("-"?(({FRAC}{EXP}?)|({DSEQ}{EXP})))
+REAL (({FRAC}{EXP}?)|({DSEQ}{EXP}))
STRING (\"([^\"\\\n]|(\\\"))*\")
IDENTIFIER ([[:alpha:]][_[:alnum:]]*)
CMPOP (([<>]=?)|([!=]=))
"remaining expressions are not evaluated at all.",
"This can be used to optimize the selections: you should write the",
"most restrictive and/or the most inexpensive expressions first in",
- "gmx_boolean expressions.",
+ "boolean expressions.",
"The relative ordering between dynamic and static expressions does not",
"matter: all static expressions are evaluated only once, before the first",
"frame, and the result becomes the leftmost expression.[PAR]",
"of groups of three or four atoms).",
"For such programs, it is up to the user to provide a proper selection",
"expression that always returns such positions.",
+ "[PAR]",
+
+ "Due to technical reasons, having a negative value as the first value in",
+ "expressions like[BR]",
+ "[TT]charge -1 to -0.7[tt][BR]",
+ "result in a syntax error. A workaround is to write[BR]",
+ "[TT]charge {-1 to -0.7}[tt][BR]",
+ "instead.",
};
static const char *help_positions[] = {
"Possible ways of specifying positions in selections are:[PAR]",
- "1. A constant position can be defined as [TT](XX, YY, ZZ)[tt], where",
+ "1. A constant position can be defined as [TT][XX, YY, ZZ][tt], where",
"[TT]XX[tt], [TT]YY[tt] and [TT]ZZ[tt] are real numbers.[PAR]",
"2. [TT]com of ATOM_EXPR [pbc][tt] or [TT]cog of ATOM_EXPR [pbc][tt]",
#endif
fr->bX = 1;
+ fr->bBox = 1;
vec[0] = .1*ts.A; vec[1] = .1*ts.B; vec[2] = .1*ts.C;
angle[0] = ts.alpha; angle[1] = ts.beta; angle[2] = ts.gamma;
matrix_convert(fr->box,vec,angle);
- fr->bTime = 1;
- fr->time = ts.physical_time;
-
+ if (fr->vmdplugin.api->abiversion>10)
+ {
+ fr->bTime = TRUE;
+ fr->time = ts.physical_time;
+ }
+ else
+ {
+ fr->bTime = FALSE;
+ }
return 1;
return 0;
}
- if (fr->natoms < 1) {
- fprintf(stderr, "\nNo atoms found by VMD plugin in %s.\n"
- "Or format does not record number of atoms.\n", fn );
+ if (fr->natoms == MOLFILE_NUMATOMS_UNKNOWN) {
+ fprintf(stderr, "\nFormat of file %s does not record number of atoms.\n", fn);
+ return 0;
+ } else if (fr->natoms == MOLFILE_NUMATOMS_NONE) {
+ fprintf(stderr, "\nNo atoms found by VMD plugin in file %s.\n", fn );
+ return 0;
+ } else if (fr->natoms < 1) { /*should not be reached*/
+ fprintf(stderr, "\nUnknown number of atoms %d for VMD plugin opening file %s.\n",
+ fr->natoms, fn );
return 0;
}
snew(fr->x,fr->natoms);
fr->vmdplugin.bV = 0;
- if (fr->vmdplugin.api->read_timestep_metadata)
+ if (fr->vmdplugin.api->abiversion > 10 && fr->vmdplugin.api->read_timestep_metadata)
{
fr->vmdplugin.api->read_timestep_metadata(fr->vmdplugin.handle, metadata);
fr->vmdplugin.bV = metadata->has_velocities;
set(MDRUN_SOURCES
gctio.c ionize.c runner.c
do_gct.c repl_ex.c xutils.c
- md.c mdrun.c genalg.c md_openmm.c)
+ md.c mdrun.c genalg.c membed.c
+ md_openmm.c)
add_library(gmxpreprocess ${GMXPREPROCESS_SOURCES})
target_link_libraries(gmxpreprocess md)
else()
add_definitions( -DOPENMM_PLUGIN_DIR="" )
endif()
- add_library(openmm_api_wrapper openmm_wrapper.cpp)
- target_link_libraries(openmm_api_wrapper gmx gmx_gpu_utils ${OpenMM_LIBRARIES})
-# remove_definitions( -DOPENMM_PLUGIN_DIR="${OpenMM_PLUGIN_DIR}" ) # TODO where should this go?!
+ 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})
- install(TARGETS openmm_api_wrapper DESTINATION ${LIB_INSTALL_DIR})
endif(GMX_OPENMM)
if(GMX_FAHCORE)
add_executable(mdrun ${MDRUN_SOURCES})
target_link_libraries(mdrun ${GMX_EXTRA_LIBRARIES} ${GMX_OPENMM_LIBRARIES})
-# set binary name to mdrun-gpu
-if(GMX_OPENMM)
- set(_mdrun_exec_name "mdrun-gpu")
-else()
- set(_mdrun_exec_name "mdrun${GMX_BINARY_SUFFIX}")
-endif()
-set_target_properties(mdrun PROPERTIES OUTPUT_NAME "${_mdrun_exec_name}")
+set_target_properties(mdrun PROPERTIES OUTPUT_NAME "mdrun${GMX_BINARY_SUFFIX}")
# this is to circumvent the following MSVC error:
# warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs
RUNTIME DESTINATION ${BIN_INSTALL_DIR})
-get_target_property(MDRUN_PATH mdrun LOCATION)
+# if we build shared gromacs libs, when installing throught the install-mdrun target
+# these libs need to be installed as well
+if(BUILD_SHARED_LIBS)
+ # in MDRUN_LIBS we store the libraries MDRUN links against (NOTE: hardcoded!!!)
+ set(MDRUN_LIBS gmxpreprocess md gmx)
+
+ # generate install-libXXX custom target for each shared lib that mdrun links against
+ foreach(_lib ${MDRUN_LIBS})
+ # double-check that the type is SHARED
+ get_target_property(_type ${_lib} TYPE)
+ if(NOT ${_type} STREQUAL "SHARED_LIBRARY")
+ message(FATAL_ERROR " Internal error: library ${_lib} is not shared so it's not supposed to be processed for installing")
+ endif()
+
+ # figure out the path and filename under which the lib will be installed
+ # (libname with pre- and suffix)
+ get_target_property(_lib_path ${_lib} LOCATION)
+ string(REGEX REPLACE "/" ";" _lib_fname ${_lib_path})
+ list(REVERSE _lib_fname)
+ list(GET _lib_fname 0 _lib_fname)
+
+ # create custom target for copying each library to the install location
+ # TODO: need to fix this to have the .so.6 form
+ add_custom_target(install-${_lib}
+ COMMAND ${CMAKE_COMMAND} -E copy
+ "${_lib_path}" "${LIB_INSTALL_DIR}/${_lib_fname}.${SOVERSION}"
+ COMMAND ${CMAKE_COMMAND} -E create_symlink
+ "${_lib_fname}.${SOVERSION}" "${LIB_INSTALL_DIR}/${_lib_fname}"
+ COMMENT "Installing library ${_lib}")
+ add_dependencies(install-${_lib} ${_lib})
+
+ # gather the custom target names in a string
+ # set(_lib_install_targets "${_lib_install_targets} install-lib${_lib}")
+ list(APPEND _lib_install_targets "install-${_lib}")
+ endforeach(_lib)
+endif(BUILD_SHARED_LIBS)
+
+get_target_property(_mdrun_path mdrun LOCATION)
add_custom_target(install-mdrun
- COMMAND ${CMAKE_COMMAND} -E copy "${MDRUN_PATH}"
- "${CMAKE_INSTALL_PREFIX}/bin/${_mdrun_exec_name}"
- DEPENDS mdrun
- COMMENT "Installing mdrun")
+ COMMAND ${CMAKE_COMMAND} -E copy "${_mdrun_path}"
+ "${BIN_INSTALL_DIR}/${_mdrun_exec_name}"
+ COMMENT "Installing mdrun")
+add_dependencies(install-mdrun mdrun ${_lib_install_targets})
endif(GMX_FAHCORE)
g_x2top_SOURCES = g_x2top.c nm2type.c g_x2top.h
mdrun_SOURCES = \
- gctio.c gmx_membed.c gmx_membed.h \
+ gctio.c membed.c membed.h \
ionize.c ionize.h xmdrun.h \
do_gct.c repl_ex.c repl_ex.h \
xutils.c runner.c md.c mdrun.c \
CUDA_INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
set(CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE OFF)
if(CMAKE_BUILD_TYPE STREQUAL "DEBUG")
- CUDA_ADD_LIBRARY(gmx_gpu_utils
- gmx_gpu_utils.cu
- memtestG80_core.cu
+ CUDA_ADD_LIBRARY(gmx_gpu_utils STATIC
+ gmx_gpu_utils.cu memtestG80_core.cu
OPTIONS ${_os_def}
- DEBUG -g -D_DEBUG_=1
- )
+ DEBUG -g -D_DEBUG_=1 )
else()
- CUDA_ADD_LIBRARY(gmx_gpu_utils
- gmx_gpu_utils.cu
- memtestG80_core.cu
- OPTIONS ${_os_def}
- )
+ CUDA_ADD_LIBRARY(gmx_gpu_utils STATIC
+ gmx_gpu_utils.cu memtestG80_core.cu
+ OPTIONS ${_os_def} )
endif()
CUDA_BUILD_CLEAN_TARGET()
-
-target_link_libraries(gmx_gpu_utils gmx)
-install(TARGETS gmx_gpu_utils DESTINATION ${LIB_INSTALL_DIR})
-
}
}
+static void check_bonds_timestep(gmx_mtop_t *mtop,double dt,warninp_t wi)
+{
+ /* This check is not intended to ensure accurate integration,
+ * rather it is to signal mistakes in the mdp settings.
+ * A common mistake is to forget to turn on constraints
+ * for MD after energy minimization with flexible bonds.
+ * This check can also detect too large time steps for flexible water
+ * models, but such errors will often be masked by the constraints
+ * mdp options, which turns flexible water into water with bond constraints,
+ * but without an angle constraint. Unfortunately such incorrect use
+ * of water models can not easily be detected without checking
+ * for specific model names.
+ *
+ * The stability limit of leap-frog or velocity verlet is 4.44 steps
+ * per oscillational period.
+ * But accurate bonds distributions are lost far before that limit.
+ * To allow relatively common schemes (although not common with Gromacs)
+ * of dt=1 fs without constraints and dt=2 fs with only H-bond constraints
+ * we set the note limit to 10.
+ */
+ int min_steps_warn=5;
+ int min_steps_note=10;
+ t_iparams *ip;
+ int molt;
+ gmx_moltype_t *moltype,*w_moltype;
+ t_atom *atom;
+ t_ilist *ilist,*ilb,*ilc,*ils;
+ int ftype;
+ int i,a1,a2,w_a1,w_a2,j;
+ real twopi2,limit2,fc,re,m1,m2,period2,w_period2;
+ gmx_bool bFound,bWater,bWarn;
+ char warn_buf[STRLEN];
+
+ ip = mtop->ffparams.iparams;
+
+ twopi2 = sqr(2*M_PI);
+
+ limit2 = sqr(min_steps_note*dt);
+
+ w_a1 = w_a2 = -1;
+ w_period2 = -1.0;
+
+ w_moltype = NULL;
+ for(molt=0; molt<mtop->nmoltype; molt++)
+ {
+ moltype = &mtop->moltype[molt];
+ atom = moltype->atoms.atom;
+ ilist = moltype->ilist;
+ ilc = &ilist[F_CONSTR];
+ ils = &ilist[F_SETTLE];
+ for(ftype=0; ftype<F_NRE; ftype++)
+ {
+ if (!(ftype == F_BONDS || ftype == F_G96BONDS || ftype == F_HARMONIC))
+ {
+ continue;
+ }
+
+ ilb = &ilist[ftype];
+ for(i=0; i<ilb->nr; i+=3)
+ {
+ fc = ip[ilb->iatoms[i]].harmonic.krA;
+ re = ip[ilb->iatoms[i]].harmonic.rA;
+ if (ftype == F_G96BONDS)
+ {
+ /* Convert squared sqaure fc to harmonic fc */
+ fc = 2*fc*re;
+ }
+ a1 = ilb->iatoms[i+1];
+ a2 = ilb->iatoms[i+2];
+ m1 = atom[a1].m;
+ m2 = atom[a2].m;
+ if (fc > 0 && m1 > 0 && m2 > 0)
+ {
+ period2 = twopi2*m1*m2/((m1 + m2)*fc);
+ }
+ else
+ {
+ period2 = GMX_FLOAT_MAX;
+ }
+ if (debug)
+ {
+ fprintf(debug,"fc %g m1 %g m2 %g period %g\n",
+ fc,m1,m2,sqrt(period2));
+ }
+ if (period2 < limit2)
+ {
+ bFound = FALSE;
+ for(j=0; j<ilc->nr; j+=3)
+ {
+ if ((ilc->iatoms[j+1] == a1 && ilc->iatoms[j+2] == a2) ||
+ (ilc->iatoms[j+1] == a2 && ilc->iatoms[j+2] == a1))
+ {
+ bFound = TRUE;
+ }
+ }
+ for(j=0; j<ils->nr; j+=2)
+ {
+ if ((a1 >= ils->iatoms[j+1] && a1 < ils->iatoms[j+1]+3) &&
+ (a2 >= ils->iatoms[j+1] && a2 < ils->iatoms[j+1]+3))
+ {
+ bFound = TRUE;
+ }
+ }
+ if (!bFound &&
+ (w_moltype == NULL || period2 < w_period2))
+ {
+ w_moltype = moltype;
+ w_a1 = a1;
+ w_a2 = a2;
+ w_period2 = period2;
+ }
+ }
+ }
+ }
+ }
+
+ if (w_moltype != NULL)
+ {
+ bWarn = (w_period2 < sqr(min_steps_warn*dt));
+ /* A check that would recognize most water models */
+ bWater = ((*w_moltype->atoms.atomname[0])[0] == 'O' &&
+ w_moltype->atoms.nr <= 5);
+ sprintf(warn_buf,"The bond in molecule-type %s between atoms %d %s and %d %s has an estimated oscillational period of %.1e ps, which is less than %d times the time step of %.1e ps.\n"
+ "%s",
+ *w_moltype->name,
+ w_a1+1,*w_moltype->atoms.atomname[w_a1],
+ w_a2+1,*w_moltype->atoms.atomname[w_a2],
+ sqrt(w_period2),bWarn ? min_steps_warn : min_steps_note,dt,
+ bWater ?
+ "Maybe you asked for fexible water." :
+ "Maybe you forgot to change the constraints mdp option.");
+ if (bWarn)
+ {
+ warning(wi,warn_buf);
+ }
+ else
+ {
+ warning_note(wi,warn_buf);
+ }
+ }
+}
+
static void check_vel(gmx_mtop_t *mtop,rvec v[])
{
gmx_mtop_atomloop_all_t aloop;
char warn_buf[STRLEN];
t_filenm fnm[] = {
- { efMDP, NULL, NULL, ffOPTRD },
+ { efMDP, NULL, NULL, ffREAD },
{ efMDP, "-po", "mdout", ffWRITE },
{ efSTX, "-c", NULL, ffREAD },
{ efSTX, "-r", NULL, ffOPTRD },
check_cg_sizes(ftp2fn(efTOP,NFILE,fnm),&sys->moltype[i].cgs,wi);
}
+ if (EI_DYNAMICS(ir->eI) && ir->eI != eiBD)
+ {
+ check_bonds_timestep(sys,ir->delta_t,wi);
+ }
+
check_warning_error(wi,FARGS);
if (bVerbose)
#include "checkpoint.h"
#include "mtop_util.h"
#include "sighandler.h"
-#include "gmx_membed.h"
+#include "membed.h"
#ifdef GMX_LIB_MPI
#include <mpi.h>
bStartingFromCpt = FALSE;
/* ####### SET VARIABLES FOR NEXT ITERATION IF THEY STILL NEED IT ###### */
- /* Complicated conditional when bGStatEveryStep=FALSE.
- * We can not just use bGStat, since then the simulation results
- * would depend on nstenergy and nstlog or step_nscheck.
+ /* With all integrators, except VV, we need to retain the pressure
+ * at the current step for coupling at the next step.
*/
- if (((state->flags & (1<<estPRES_PREV)) ||
- (state->flags & (1<<estSVIR_PREV)) ||
- (state->flags & (1<<estFVIR_PREV))) &&
+ if ((state->flags & (1<<estPRES_PREV)) &&
(bGStatEveryStep ||
- (ir->nstlist > 0 && step % ir->nstlist == 0) ||
- (ir->nstlist < 0 && nlh.nabnsb > 0) ||
- (ir->nstlist == 0 && bGStat)))
+ (ir->nstpcouple > 0 && step % ir->nstpcouple == 0)))
{
/* Store the pressure in t_state for pressure coupling
* at the next MD step.
*/
- if (state->flags & (1<<estPRES_PREV))
- {
- copy_mat(pres,state->pres_prev);
- }
+ copy_mat(pres,state->pres_prev);
}
/* ####### END SET VARIABLES FOR NEXT ITERATION ###### */
#include "genborn.h"
#include "string2.h"
#include "copyrite.h"
-#include "gmx_membed.h"
+#include "membed.h"
#ifdef GMX_THREADS
#include "tmpi.h"
const char *ommOptions = NULL;
void *openmmData;
+#ifdef GMX_DOUBLE
+ /* Checks in cmake should prevent the compilation in double precision
+ * with OpenMM, but just to be sure we check here.
+ */
+ gmx_fatal(FARGS,"Compilation was performed in double precision, but OpenMM only supports single precision. If you want to use to OpenMM, compile in single precision.");
+#endif
+
bAppend = (Flags & MD_APPENDFILES);
check_ir_old_tpx_versions(cr,fplog,ir,top_global);
openmm_copy_state(openmmData, state, &t, f, enerd, bX, bV, bF, do_ene);
- upd_mdebin(mdebin, FALSE,TRUE,
+ upd_mdebin(mdebin,FALSE,TRUE,
t,mdatoms->tmass,enerd,state,lastbox,
shake_vir,force_vir,total_vir,pres,
ekind,mu_tot,constr);
#include "mtop_util.h"
#include "tpxio.h"
#include "string2.h"
-#include "gmx_membed.h"
+#include "membed.h"
#include "pbc.h"
#include "readinp.h"
* not be zero at the cut-off.
*/
if (EVDW_IS_ZERO_AT_CUTOFF(ir->vdwtype) &&
- rvdw1 + rvdw2 > ir->rlistlong - ir->rvdw)
+ rvdw1 + rvdw2 > ir->rlist - ir->rvdw)
{
- sprintf(warn_buf,"The sum of the two largest charge group radii (%f) is larger than %s (%f) - rvdw (%f)\n",
+ sprintf(warn_buf,"The sum of the two largest charge group radii (%f) is larger than rlist (%f) - rvdw (%f)\n",
rvdw1+rvdw2,
- ir->rlistlong > ir->rlist ? "rlistlong" : "rlist",
ir->rlist,ir->rvdw);
if (ir_NVE(ir))
{
#include "mdrun.h"
#include "network.h"
#include "pull.h"
+#include "pull_rotation.h"
#include "names.h"
#include "disre.h"
#include "orires.h"
#include "sighandler.h"
#include "tpxio.h"
#include "txtdump.h"
-#include "pull_rotation.h"
-#include "gmx_membed.h"
+#include "membed.h"
+
#include "md_openmm.h"
#ifdef GMX_LIB_MPI
/* PME, if used, is done on all nodes with 1D decomposition */
cr->npmenodes = 0;
cr->duty = (DUTY_PP | DUTY_PME);
- npme_major = cr->nnodes;
+ npme_major = 1;
npme_minor = 1;
+ if (!EI_TPI(inputrec->eI))
+ {
+ npme_major = cr->nnodes;
+ }
if (inputrec->ePBC == epbcSCREW)
{
{
pme_flags |= GMX_PME_CALC_ENER_VIR;
}
+ if (fr->n_tpi > 0)
+ {
+ /* We don't calculate f, but we do want the potential */
+ pme_flags |= GMX_PME_CALC_POT;
+ }
wallcycle_start(wcycle,ewcPMEMESH);
status = gmx_pme_do(fr->pmedata,
md->start,md->homenr - fr->n_tpi,
void set_avcsixtwelve(FILE *fplog,t_forcerec *fr,const gmx_mtop_t *mtop)
{
- const t_atoms *atoms;
+ const t_atoms *atoms,*atoms_tpi;
const t_blocka *excl;
int mb,nmol,nmolc,i,j,tpi,tpj,j1,j2,k,n,nexcl,q;
#if (defined SIZEOF_LONG_LONG_INT) && (SIZEOF_LONG_LONG_INT >= 8)
/* Only correct for the interaction of the test particle
* with the rest of the system.
*/
- atoms = &mtop->moltype[mtop->molblock[mtop->nmolblock-1].type].atoms;
- if (q == 0)
- {
- tpi = atoms->atom[atoms->nr-1].type;
- }
- else
- {
- tpi = atoms->atom[atoms->nr-1].typeB;
- }
+ atoms_tpi =
+ &mtop->moltype[mtop->molblock[mtop->nmolblock-1].type].atoms;
+
npair = 0;
for(mb=0; mb<mtop->nmolblock; mb++) {
nmol = mtop->molblock[mb].nmol;
/* Remove the interaction of the test charge group
* with itself.
*/
- if (mb == mtop->nmolblock-1 && j >= atoms->nr - fr->n_tpi)
+ if (mb == mtop->nmolblock-1)
{
nmolc--;
+
+ if (mb == 0 && nmol == 1)
+ {
+ gmx_fatal(FARGS,"Old format tpr with TPI, please generate a new tpr file");
+ }
}
if (q == 0)
{
{
tpj = atoms->atom[j].typeB;
}
- if (bBHAM)
- {
- csix += nmolc*BHAMC(nbfp,ntp,tpi,tpj);
- }
- else
+ for(i=0; i<fr->n_tpi; i++)
{
- csix += nmolc*C6 (nbfp,ntp,tpi,tpj);
- ctwelve += nmolc*C12(nbfp,ntp,tpi,tpj);
+ if (q == 0)
+ {
+ tpi = atoms_tpi->atom[i].type;
+ }
+ else
+ {
+ tpi = atoms_tpi->atom[i].typeB;
+ }
+ if (bBHAM)
+ {
+ csix += nmolc*BHAMC(nbfp,ntp,tpi,tpj);
+ }
+ else
+ {
+ csix += nmolc*C6 (nbfp,ntp,tpi,tpj);
+ ctwelve += nmolc*C12(nbfp,ntp,tpi,tpj);
+ }
+ npair += nmolc;
}
- npair += nmolc;
}
}
}
#define FFTW_UNLOCK
#endif /* GMX_THREADS */
+/* We assume here that aligned memory starts at multiple of 16 bytes and unaligned memory starts at multiple of 8 bytes. The later is guranteed for all malloc implementation.
+ Consequesences:
+ - It is not allowed to use these FFT plans from memory which doesn't have a starting address as a multiple of 8 bytes.
+ This is OK as long as the memory directly comes from malloc and is not some subarray within alloated memory.
+ - This has to be fixed if any future architecute requires memory to be aligned to multiples of 32 bytes.
+*/
+
struct gmx_fft
{
/* Three alternatives (unaligned/aligned, out-of-place/in-place, forward/backward)
void * in_data,
void * out_data)
{
- int aligned = (((size_t)in_data & (size_t)out_data & 0xf)==0);
+ int aligned = ((((size_t)in_data | (size_t)out_data) & 0xf)==0);
int inplace = (in_data == out_data);
int isforward = (dir == GMX_FFT_FORWARD);
void * in_data,
void * out_data)
{
- int aligned = (((size_t)in_data & (size_t)out_data & 0xf)==0);
+ int aligned = ((((size_t)in_data | (size_t)out_data) & 0xf)==0);
int inplace = (in_data == out_data);
int isforward = (dir == GMX_FFT_REAL_TO_COMPLEX);
void * in_data,
void * out_data)
{
- int aligned = (((size_t)in_data & (size_t)out_data & 0xf)==0);
+ int aligned = ((((size_t)in_data | (size_t)out_data) & 0xf)==0);
int inplace = (in_data == out_data);
int isforward = (dir == GMX_FFT_FORWARD);
void * in_data,
void * out_data)
{
- int aligned = (((size_t)in_data & (size_t)out_data & 0xf)==0);
+ int aligned = ((((size_t)in_data | (size_t)out_data) & 0xf)==0);
int inplace = (in_data == out_data);
int isforward = (dir == GMX_FFT_REAL_TO_COMPLEX);
void * in_data,
void * out_data)
{
- int aligned = (((size_t)in_data & (size_t)out_data & 0xf)==0);
+ int aligned = ((((size_t)in_data | (size_t)out_data) & 0xf)==0);
int inplace = (in_data == out_data);
int isforward = (dir == GMX_FFT_FORWARD);
void * in_data,
void * out_data)
{
- int aligned = (((size_t)in_data & (size_t)out_data & 0xf)==0);
+ int aligned = ((((size_t)in_data | (size_t)out_data) & 0xf)==0);
int inplace = (in_data == out_data);
int isforward = (dir == GMX_FFT_REAL_TO_COMPLEX);
md->bEInd[i]=FALSE;
}
- for(i=0; i<F_NRE; i++) {
+#ifndef GMX_OPENMM
+ for(i=0; i<F_NRE; i++)
+ {
md->bEner[i] = FALSE;
if (i == F_LJ)
md->bEner[i] = !bBHAM;
else
md->bEner[i] = (gmx_mtop_ftype_count(mtop,i) > 0);
}
+#else
+ /* OpenMM always produces only the following 4 energy terms */
+ md->bEner[F_EPOT] = TRUE;
+ md->bEner[F_EKIN] = TRUE;
+ md->bEner[F_ETOT] = TRUE;
+ md->bEner[F_TEMP] = TRUE;
+#endif
md->f_nre=0;
for(i=0; i<F_NRE; i++)
#include "mtop_util.h"
#include "gmxfio.h"
#include "pme.h"
-#include "gmx_membed.h"
+#include "membed.h"
typedef struct {
t_state s;
pme->nnodes_minor = nnodes_minor;
#ifdef GMX_MPI
- if (PAR(cr))
+ if (nnodes_major*nnodes_minor > 1 && PAR(cr))
{
pme->mpi_comm = cr->mpi_comm_mygroup;
MPI_Comm_rank(pme->mpi_comm,&pme->nodeid);
MPI_Comm_size(pme->mpi_comm,&pme->nnodes);
+ if (pme->nnodes != nnodes_major*nnodes_minor)
+ {
+ gmx_incons("PME node count mismatch");
+ }
}
#endif
inc_nrnb(nrnb,eNR_SOLVEPME,loop_count);
}
- if (flags & GMX_PME_CALC_F)
+ if ((flags & GMX_PME_CALC_F) ||
+ (flags & GMX_PME_CALC_POT))
{
/* do 3d-invfft */
}
#endif
where();
+ }
+ if (flags & GMX_PME_CALC_F)
+ {
unwrap_periodic_pmegrid(pme,grid);
/* interpolate forces for our local atoms */
gmx_editconf.c gmx_genbox.c gmx_genion.c gmx_genconf.c
gmx_genpr.c gmx_eneconv.c gmx_vanhove.c gmx_wheel.c
addconf.c calcpot.c edittop.c gmx_bar.c
- gmx_membed.c gmx_pme_error.c )
+ gmx_pme_error.c )
target_link_libraries(gmxana md gmx)
g_rmsf g_rotacf g_saltbr g_sas g_select g_sgangle g_sham g_sorient
g_spol g_spatial g_tcaf g_traj g_tune_pme g_vanhove
g_velacc g_clustsize g_mdmat g_wham g_sigeps g_bar
- g_membed g_pme_error g_rmsdist g_rotmat)
+ g_pme_error g_rmsdist g_rotmat)
gmx_polystat.c gmx_potential.c gmx_rama.c \
gmx_rdf.c gmx_rms.c gmx_rmsdist.c gmx_rmsf.c \
gmx_rotacf.c gmx_rotmat.c gmx_saltbr.c gmx_sas.c \
- gmx_select.c gmx_pme_error.c \
+ gmx_select.c gmx_pme_error.c gmx_membed.c \
gmx_sgangle.c gmx_sorient.c gmx_spol.c gmx_tcaf.c \
gmx_traj.c gmx_velacc.c gmx_helixorient.c \
gmx_clustsize.c gmx_mdmat.c gmx_wham.c eigio.h \
gmx_trjconv.c gmx_trjcat.c gmx_trjorder.c gmx_xpm2ps.c \
gmx_editconf.c gmx_genbox.c gmx_genion.c gmx_genconf.c \
gmx_genpr.c gmx_eneconv.c gmx_vanhove.c gmx_wheel.c \
- addconf.c addconf.h gmx_tune_pme.c gmx_membed.c \
+ addconf.c addconf.h gmx_tune_pme.c \
calcpot.c calcpot.h edittop.c
bin_PROGRAMS = \
g_enemat g_energy g_lie g_filter \
g_gyrate g_h2order g_hbond g_helix \
g_mindist g_msd g_morph g_nmeig \
- g_nmens g_order \
+ g_nmens g_order g_membed \
g_polystat g_potential g_rama \
g_rdf g_rms g_rmsdist g_rmsf \
g_rotacf g_rotmat g_saltbr g_sas \
g_sham g_sorient g_spol \
g_spatial g_pme_error \
g_tcaf g_traj g_tune_pme \
- g_vanhove g_velacc g_membed \
+ g_vanhove g_velacc \
g_clustsize g_mdmat g_wham \
g_sigeps
#include "smalloc.h"
#include "gstat.h"
#include "gmx_fatal.h"
+#include "index.h"
t_dlist *mk_dlist(FILE *log,
t_atoms *atoms, int *nlist,
gmx_bool bPhi, gmx_bool bPsi, gmx_bool bChi, gmx_bool bHChi,
- int maxchi,int r0,int naa,char **aa)
+ int maxchi, int r0, gmx_residuetype_t rt)
{
int ires,i,j,k,ii;
t_dihatms atm,prev;
}
if ((atm.minC != -1) && (atm.minO != -1))
nc[6]++;
- for(k=0; (k<naa); k++) {
- if (gmx_strcasecmp(aa[k],thisres) == 0)
- break;
- }
- dl[nl].index=k;
+ dl[nl].index=gmx_residuetype_get_index(rt,thisres);
sprintf(dl[nl].name,"%s%d",thisres,ires+r0);
nl++;
return j ;
}
-static void histogramming(FILE *log,int nbin, int naa,char **aa,
+static void histogramming(FILE *log,int nbin,gmx_residuetype_t rt,
int nf,int maxchi,real **dih,
int nlist,t_dlist dlist[],
atom_id index[],
gmx_bool bBfac,bOccup;
char hisfile[256],hhisfile[256],sshisfile[256],title[256],*ss_str=NULL;
char **leg;
-
+ const char *residue_name;
+ int rt_size;
+
+ rt_size = gmx_residuetype_get_size(rt);
if (bSSHisto) {
fp = ffopen(ssdump,"r");
if(1 != fscanf(fp,"%d",&nres))
/* Four dimensional array... Very cool */
snew(his_aa_ss,3);
for(i=0; (i<3); i++) {
- snew(his_aa_ss[i],naa+1);
- for(j=0; (j<=naa); j++) {
+ snew(his_aa_ss[i],rt_size+1);
+ for(j=0; (j<=rt_size); j++) {
snew(his_aa_ss[i][j],edMax);
for(Dih=0; (Dih<edMax); Dih++)
snew(his_aa_ss[i][j][Dih],nbin+1);
}
snew(his_aa,edMax);
for(Dih=0; (Dih<edMax); Dih++) {
- snew(his_aa[Dih],naa+1);
- for(i=0; (i<=naa); i++) {
+ snew(his_aa[Dih],rt_size+1);
+ for(i=0; (i<=rt_size); i++) {
snew(his_aa[Dih][i],nbin+1);
}
}
/* finished -jc stuff */
snew(normhisto,nbin);
- for(i=0; (i<naa); i++) {
+ for(i=0; (i<rt_size); i++) {
for(Dih=0; (Dih<edMax); Dih++){
/* First check whether something is in there */
for(j=0; (j<nbin); j++)
if (bNormalize)
normalize_histo(nbin,his_aa[Dih][i],(360.0/nbin),normhisto);
+ residue_name = gmx_residuetype_get_name(rt,i);
switch (Dih) {
case edPhi:
- sprintf(hisfile,"histo-phi%s",aa[i]);
- sprintf(title,"\\xf\\f{} Distribution for %s",aa[i]);
+ sprintf(hisfile,"histo-phi%s",residue_name);
+ sprintf(title,"\\xf\\f{} Distribution for %s",residue_name);
break;
case edPsi:
- sprintf(hisfile,"histo-psi%s",aa[i]);
- sprintf(title,"\\xy\\f{} Distribution for %s",aa[i]);
+ sprintf(hisfile,"histo-psi%s",residue_name);
+ sprintf(title,"\\xy\\f{} Distribution for %s",residue_name);
break;
case edOmega:
- sprintf(hisfile,"histo-omega%s",aa[i]);
- sprintf(title,"\\xw\\f{} Distribution for %s",aa[i]);
+ sprintf(hisfile,"histo-omega%s",residue_name);
+ sprintf(title,"\\xw\\f{} Distribution for %s",residue_name);
break;
default:
- sprintf(hisfile,"histo-chi%d%s",Dih-NONCHI+1,aa[i]);
+ sprintf(hisfile,"histo-chi%d%s",Dih-NONCHI+1,residue_name);
sprintf(title,"\\xc\\f{}\\s%d\\N Distribution for %s",
- Dih-NONCHI+1,aa[i]);
+ Dih-NONCHI+1,residue_name);
}
strcpy(hhisfile,hisfile);
strcat(hhisfile,".xvg");
if (bSSHisto) {
/* Four dimensional array... Very cool */
for(i=0; (i<3); i++) {
- for(j=0; (j<=naa); j++) {
+ for(j=0; (j<=rt_size); j++) {
for(Dih=0; (Dih<edMax); Dih++)
sfree(his_aa_ss[i][j][Dih]);
sfree(his_aa_ss[i][j]);
};
FILE *log;
- int natoms,nlist,naa,idum,nbin;
+ int natoms,nlist,idum,nbin;
t_atoms atoms;
rvec *x;
int ePBC;
matrix box;
char title[256],grpname[256];
t_dlist *dlist;
- char **aa;
gmx_bool bChi,bCorr,bSSHisto;
gmx_bool bDo_rt, bDo_oh, bDo_ot, bDo_jc ;
real dt=0, traj_t_ns;
output_env_t oenv;
+ gmx_residuetype_t rt;
atom_id isize,*index;
int ndih,nactdih,nf;
read_stx_conf(ftp2fn(efSTX,NFILE,fnm),title,&atoms,x,NULL,&ePBC,box);
fprintf(log,"Title: %s\n",title);
- naa=get_strings("aminoacids.dat",&aa);
- dlist=mk_dlist(log,&atoms,&nlist,bPhi,bPsi,bChi,bHChi,maxchi,r0,naa,aa);
+ gmx_residuetype_init(&rt);
+ dlist=mk_dlist(log,&atoms,&nlist,bPhi,bPsi,bChi,bHChi,maxchi,r0,rt);
fprintf(stderr,"%d residues with dihedrals found\n", nlist);
if (nlist == 0)
dump_em_all(nlist,dlist,nf,time,dih,maxchi,bPhi,bPsi,bChi,bOmega,bRAD,oenv);
/* Histogramming & J coupling constants & calc of S2 order params */
- histogramming(log,nbin,naa,aa,nf,maxchi,dih,nlist,dlist,index,
+ histogramming(log,nbin,rt,nf,maxchi,dih,nlist,dlist,index,
bPhi,bPsi,bOmega,bChi,
bNormHisto,bSSHisto,ftp2fn(efDAT,NFILE,fnm),bfac_max,&atoms,
bDo_jc,opt2fn("-jc",NFILE,fnm),oenv);
if (bCorr)
do_view(oenv,opt2fn("-corr",NFILE,fnm),"-nxy");
+ gmx_residuetype_destroy(rt);
+
thanx(stderr);
return 0;
int gmx_density(int argc,char *argv[])
{
const char *desc[] = {
- "Compute partial densities across the box, using an index file. Densities",
- "in kg/m^3, number densities or electron densities can be",
+ "Compute partial densities across the box, using an index file.[PAR]",
+ "For the total density of NPT simulations, use [TT]g_energy[tt] instead.",
+ "[PAR]",
+ "Densities in kg/m^3, number densities or electron densities can be",
"calculated. For electron densities, a file describing the number of",
"electrons for each type of atom should be provided using [TT]-ei[tt].",
"It should look like:[BR]",
void sort_molecule(t_atoms **atoms_solvt,rvec *x,rvec *v,real *r)
{
- int atnr,i,j,moltp=0,nrmoltypes,resnr;
+ int atnr,i,j,moltp=0,nrmoltypes,resi_o,resi_n,resnr;
t_moltypes *moltypes;
- int *tps;
t_atoms *atoms,*newatoms;
rvec *newx, *newv=NULL;
real *newr;
atoms = *atoms_solvt;
/* copy each residue from *atoms to a molecule in *molecule */
- snew(tps,atoms->nr);
moltypes=NULL;
nrmoltypes=0;
atnr=0;
}
moltypes[moltp].nmol++;
}
- tps[i]=moltp;
}
fprintf(stderr,"Found %d%s molecule type%s:\n",
if (v) snew(newv,atoms->nr);
snew(newr,atoms->nr);
- for (i=0; i<atoms->nr; i++) {
- resnr = moltypes[tps[i]].res0 +
- (moltypes[tps[i]].i-moltypes[tps[i]].i0) / moltypes[tps[i]].natoms;
- newatoms->atom[moltypes[tps[i]].i].resind = resnr;
- newatoms->resinfo[resnr] = atoms->resinfo[atoms->atom[i].resind];
- newatoms->resinfo[resnr].nr = resnr + 1;
- newatoms->atomname[moltypes[tps[i]].i] = atoms->atomname[i];
- newatoms->atom[moltypes[tps[i]].i] = atoms->atom[i];
- copy_rvec(x[i],newx[moltypes[tps[i]].i]);
- if (v) copy_rvec(v[i],newv[moltypes[tps[i]].i]);
- newr[moltypes[tps[i]].i] = r[i];
- moltypes[tps[i]].i++;
+ resi_n = 0;
+ resnr = 1;
+ j = 0;
+ for(moltp=0; moltp<nrmoltypes; moltp++) {
+ i = 0;
+ while (i < atoms->nr) {
+ resi_o = atoms->atom[i].resind;
+ if (strcmp(*atoms->resinfo[resi_o].name,moltypes[moltp].name) == 0) {
+ /* Copy the residue info */
+ newatoms->resinfo[resi_n] = atoms->resinfo[resi_o];
+ newatoms->resinfo[resi_n].nr = resnr;
+ /* Copy the atom info */
+ do {
+ newatoms->atom[j] = atoms->atom[i];
+ newatoms->atomname[j] = atoms->atomname[i];
+ newatoms->atom[j].resind = resi_n;
+ copy_rvec(x[i],newx[j]);
+ if (v != NULL) {
+ copy_rvec(v[i],newv[j]);
+ }
+ newr[j] = r[i];
+ i++;
+ j++;
+ } while (i < atoms->nr && atoms->atom[i].resind == resi_o);
+ /* Increase the new residue counters */
+ resi_n++;
+ resnr++;
+ } else {
+ /* Skip this residue */
+ do {
+ i++;
+ } while (i < atoms->nr && atoms->atom[i].resind == resi_o);
+ }
+ }
}
/* put them back into the original arrays and throw away temporary arrays */
#include "main.h"
#include "gmx_ana.h"
-#ifdef GMX_LIB_MPI
-#include <mpi.h>
-#endif
-#ifdef GMX_THREADS
-#include "tmpi.h"
-#endif
-
-/* afm stuf */
-#include "pull.h"
-
-/* We use the same defines as in mvdata.c here */
-#define block_bc(cr, d) gmx_bcast( sizeof(d), &(d),(cr))
-#define nblock_bc(cr,nr,d) gmx_bcast((nr)*sizeof((d)[0]), (d),(cr))
-#define snew_bc(cr,d,nr) { if (!MASTER(cr)) snew((d),(nr)); }
-
-/* The following two variables and the signal_handler function
- * is used from pme.c as well
- */
-
-typedef struct {
- t_state s;
- rvec *f;
- real epot;
- real fnorm;
- real fmax;
- int a_fmax;
-} em_state_t;
-
-typedef struct {
- int it_xy;
- int it_z;
- int xy_step;
- int z_step;
- rvec xmin;
- rvec xmax;
- rvec *geom_cent;
- int pieces;
- int *nidx;
- atom_id **subindex;
-} pos_ins_t;
-
-typedef struct {
- int id;
- char *name;
- int nr;
- int natoms; /*nr of atoms per lipid*/
- int mol1; /*id of the first lipid molecule*/
- real area;
-} lip_t;
-
-typedef struct {
- char *name;
- t_block mem_at;
- int *mol_id;
- int nmol;
- real lip_area;
- real zmin;
- real zmax;
- real zmed;
-} mem_t;
-
-typedef struct {
- int *mol;
- int *block;
- int nr;
-} rm_t;
-
-int search_string(char *s,int ng,char ***gn)
-{
- int i;
-
- for(i=0; (i<ng); i++)
- if (gmx_strcasecmp(s,*gn[i]) == 0)
- return i;
-
- gmx_fatal(FARGS,"Group %s not found in indexfile.\nMaybe you have non-default groups in your mdp file, while not using the '-n' option of grompp.\nIn that case use the '-n' option.\n",s);
-
- return -1;
-}
-
-int get_mol_id(int at,int nmblock,gmx_molblock_t *mblock, int *type, int *block)
-{
- int mol_id=0;
- int i;
-
- for(i=0;i<nmblock;i++)
- {
- if(at<(mblock[i].nmol*mblock[i].natoms_mol))
- {
- mol_id+=at/mblock[i].natoms_mol;
- *type = mblock[i].type;
- *block = i;
- return mol_id;
- } else {
- at-= mblock[i].nmol*mblock[i].natoms_mol;
- mol_id+=mblock[i].nmol;
- }
- }
-
- gmx_fatal(FARGS,"Something is wrong in mol ids, at %d, mol_id %d",at,mol_id);
-
- return -1;
-}
-
-int get_block(int mol_id,int nmblock,gmx_molblock_t *mblock)
-{
- int i;
- int nmol=0;
-
- for(i=0;i<nmblock;i++)
- {
- nmol+=mblock[i].nmol;
- if(mol_id<nmol)
- return i;
- }
-
- gmx_fatal(FARGS,"mol_id %d larger than total number of molecules %d.\n",mol_id,nmol);
-
- return -1;
-}
-
-int get_tpr_version(const char *infile)
-{
- char buf[STRLEN];
- gmx_bool bDouble;
- int precision,fver;
- t_fileio *fio;
-
- fio = open_tpx(infile,"r");
- gmx_fio_checktype(fio);
-
- precision = sizeof(real);
-
- gmx_fio_do_string(fio,buf);
- if (strncmp(buf,"VERSION",7))
- gmx_fatal(FARGS,"Can not read file %s,\n"
- " this file is from a Gromacs version which is older than 2.0\n"
- " Make a new one with grompp or use a gro or pdb file, if possible",
- gmx_fio_getname(fio));
- gmx_fio_do_int(fio,precision);
- bDouble = (precision == sizeof(double));
- if ((precision != sizeof(float)) && !bDouble)
- gmx_fatal(FARGS,"Unknown precision in file %s: real is %d bytes "
- "instead of %d or %d",
- gmx_fio_getname(fio),precision,sizeof(float),sizeof(double));
- gmx_fio_setprecision(fio,bDouble);
- fprintf(stderr,"Reading file %s, %s (%s precision)\n",
- gmx_fio_getname(fio),buf,bDouble ? "double" : "single");
-
- gmx_fio_do_int(fio,fver);
-
- close_tpx(fio);
-
- return fver;
-}
-
-void set_inbox(int natom, rvec *x)
-{
- rvec tmp;
- int i;
-
- tmp[XX]=tmp[YY]=tmp[ZZ]=0.0;
- for(i=0;i<natom;i++)
- {
- if(x[i][XX]<tmp[XX]) tmp[XX]=x[i][XX];
- if(x[i][YY]<tmp[YY]) tmp[YY]=x[i][YY];
- if(x[i][ZZ]<tmp[ZZ]) tmp[ZZ]=x[i][ZZ];
- }
-
- for(i=0;i<natom;i++)
- rvec_inc(x[i],tmp);
-}
-
-int get_mtype_list(t_block *at, gmx_mtop_t *mtop, t_block *tlist)
-{
- int i,j,nr,mol_id;
- int type=0,block=0;
- gmx_bool bNEW;
-
- nr=0;
- snew(tlist->index,at->nr);
- for (i=0;i<at->nr;i++)
- {
- bNEW=TRUE;
- mol_id = get_mol_id(at->index[i],mtop->nmolblock,mtop->molblock,&type,&block);
- for(j=0;j<nr;j++)
- {
- if(tlist->index[j]==type)
- bNEW=FALSE;
- }
- if(bNEW==TRUE)
- {
- tlist->index[nr]=type;
- nr++;
- }
- }
-
- srenew(tlist->index,nr);
- return nr;
-}
-
-void check_types(t_block *ins_at,t_block *rest_at,gmx_mtop_t *mtop)
-{
- t_block *ins_mtype,*rest_mtype;
- int i,j;
-
- snew(ins_mtype,1);
- snew(rest_mtype,1);
- ins_mtype->nr = get_mtype_list(ins_at , mtop, ins_mtype );
- rest_mtype->nr = get_mtype_list(rest_at, mtop, rest_mtype);
-
- for(i=0;i<ins_mtype->nr;i++)
- {
- for(j=0;j<rest_mtype->nr;j++)
- {
- if(ins_mtype->index[i]==rest_mtype->index[j])
- gmx_fatal(FARGS,"Moleculetype %s is found both in the group to insert and the rest of the system.\n"
- "Because we need to exclude all interactions between the atoms in the group to\n"
- "insert, the same moleculetype can not be used in both groups. Change the\n"
- "moleculetype of the molecules %s in the inserted group. Do not forget to provide\n"
- "an appropriate *.itp file",*(mtop->moltype[rest_mtype->index[j]].name),
- *(mtop->moltype[rest_mtype->index[j]].name));
- }
- }
-
- sfree(ins_mtype->index);
- sfree(rest_mtype->index);
- sfree(ins_mtype);
- sfree(rest_mtype);
-}
-
-int init_ins_at(t_block *ins_at,t_block *rest_at,t_state *state, pos_ins_t *pos_ins,gmx_groups_t *groups,int ins_grp_id, real xy_max)
-{
- int i,gid,c=0;
- real x,xmin,xmax,y,ymin,ymax,z,zmin,zmax;
-
- snew(rest_at->index,state->natoms);
-
- xmin=xmax=state->x[ins_at->index[0]][XX];
- ymin=ymax=state->x[ins_at->index[0]][YY];
- zmin=zmax=state->x[ins_at->index[0]][ZZ];
-
- for(i=0;i<state->natoms;i++)
- {
- gid = groups->grpnr[egcFREEZE][i];
- if(groups->grps[egcFREEZE].nm_ind[gid]==ins_grp_id)
- {
- x=state->x[i][XX];
- if (x<xmin) xmin=x;
- if (x>xmax) xmax=x;
- y=state->x[i][YY];
- if (y<ymin) ymin=y;
- if (y>ymax) ymax=y;
- z=state->x[i][ZZ];
- if (z<zmin) zmin=z;
- if (z>zmax) zmax=z;
- } else {
- rest_at->index[c]=i;
- c++;
- }
- }
-
- rest_at->nr=c;
- srenew(rest_at->index,c);
-
- if(xy_max>1.000001)
- {
- pos_ins->xmin[XX]=xmin-((xmax-xmin)*xy_max-(xmax-xmin))/2;
- pos_ins->xmin[YY]=ymin-((ymax-ymin)*xy_max-(ymax-ymin))/2;
-
- pos_ins->xmax[XX]=xmax+((xmax-xmin)*xy_max-(xmax-xmin))/2;
- pos_ins->xmax[YY]=ymax+((ymax-ymin)*xy_max-(ymax-ymin))/2;
- } else {
- pos_ins->xmin[XX]=xmin;
- pos_ins->xmin[YY]=ymin;
-
- pos_ins->xmax[XX]=xmax;
- pos_ins->xmax[YY]=ymax;
- }
-
- /* 6.0 is estimated thickness of bilayer */
- if( (zmax-zmin) < 6.0 )
- {
- pos_ins->xmin[ZZ]=zmin+(zmax-zmin)/2.0-3.0;
- pos_ins->xmax[ZZ]=zmin+(zmax-zmin)/2.0+3.0;
- } else {
- pos_ins->xmin[ZZ]=zmin;
- pos_ins->xmax[ZZ]=zmax;
- }
-
- return c;
-}
-
-real est_prot_area(pos_ins_t *pos_ins,rvec *r,t_block *ins_at, mem_t *mem_p)
-{
- real x,y,dx=0.15,dy=0.15,area=0.0;
- real add;
- int c,at;
-
- for(x=pos_ins->xmin[XX];x<pos_ins->xmax[XX];x+=dx)
- {
- for(y=pos_ins->xmin[YY];y<pos_ins->xmax[YY];y+=dy)
- {
- c=0;
- add=0.0;
- do
- {
- at=ins_at->index[c];
- if ( (r[at][XX]>=x) && (r[at][XX]<x+dx) &&
- (r[at][YY]>=y) && (r[at][YY]<y+dy) &&
- (r[at][ZZ]>mem_p->zmin+1.0) && (r[at][ZZ]<mem_p->zmax-1.0) )
- add=1.0;
- c++;
- } while ( (c<ins_at->nr) && (add<0.5) );
- area+=add;
- }
- }
- area=area*dx*dy;
-
- return area;
-}
-
-void init_lip(matrix box, gmx_mtop_t *mtop, lip_t *lip)
-{
- int i;
- real mem_area;
- int mol1=0;
-
- mem_area = box[XX][XX]*box[YY][YY]-box[XX][YY]*box[YY][XX];
- for(i=0;i<mtop->nmolblock;i++)
- {
- if(mtop->molblock[i].type == lip->id)
- {
- lip->nr=mtop->molblock[i].nmol;
- lip->natoms=mtop->molblock[i].natoms_mol;
- }
- }
- lip->area=2.0*mem_area/(double)lip->nr;
-
- for (i=0;i<lip->id;i++)
- mol1+=mtop->molblock[i].nmol;
- lip->mol1=mol1;
-}
-
-int init_mem_at(mem_t *mem_p, gmx_mtop_t *mtop, rvec *r, matrix box, pos_ins_t *pos_ins)
-{
- int i,j,at,mol,nmol,nmolbox,count;
- t_block *mem_a;
- real z,zmin,zmax,mem_area;
- gmx_bool bNew;
- atom_id *mol_id;
- int type=0,block=0;
-
- nmol=count=0;
- mem_a=&(mem_p->mem_at);
- snew(mol_id,mem_a->nr);
-/* snew(index,mem_a->nr); */
- zmin=pos_ins->xmax[ZZ];
- zmax=pos_ins->xmin[ZZ];
- for(i=0;i<mem_a->nr;i++)
- {
- at=mem_a->index[i];
- if( (r[at][XX]>pos_ins->xmin[XX]) && (r[at][XX]<pos_ins->xmax[XX]) &&
- (r[at][YY]>pos_ins->xmin[YY]) && (r[at][YY]<pos_ins->xmax[YY]) &&
- (r[at][ZZ]>pos_ins->xmin[ZZ]) && (r[at][ZZ]<pos_ins->xmax[ZZ]) )
- {
- mol = get_mol_id(at,mtop->nmolblock,mtop->molblock,&type,&block);
-
- bNew=TRUE;
- for(j=0;j<nmol;j++)
- if(mol == mol_id[j])
- bNew=FALSE;
-
- if(bNew)
- {
- mol_id[nmol]=mol;
- nmol++;
- }
-
- z=r[at][ZZ];
- if(z<zmin) zmin=z;
- if(z>zmax) zmax=z;
-
-/* index[count]=at;*/
- count++;
- }
- }
-
- mem_p->nmol=nmol;
- srenew(mol_id,nmol);
- mem_p->mol_id=mol_id;
-/* srenew(index,count);*/
-/* mem_p->mem_at.nr=count;*/
-/* sfree(mem_p->mem_at.index);*/
-/* mem_p->mem_at.index=index;*/
-
- if((zmax-zmin)>(box[ZZ][ZZ]-0.5))
- gmx_fatal(FARGS,"Something is wrong with your membrane. Max and min z values are %f and %f.\n"
- "Maybe your membrane is not centered in the box, but located at the box edge in the z-direction,\n"
- "so that one membrane is distributed over two periodic box images. Another possibility is that\n"
- "your water layer is not thick enough.\n",zmax,zmin);
- mem_p->zmin=zmin;
- mem_p->zmax=zmax;
- mem_p->zmed=(zmax-zmin)/2+zmin;
-
- /*number of membrane molecules in protein box*/
- nmolbox = count/mtop->molblock[block].natoms_mol;
- /*mem_area = box[XX][XX]*box[YY][YY]-box[XX][YY]*box[YY][XX];
- mem_p->lip_area = 2.0*mem_area/(double)mem_p->nmol;*/
- mem_area = (pos_ins->xmax[XX]-pos_ins->xmin[XX])*(pos_ins->xmax[YY]-pos_ins->xmin[YY]);
- mem_p->lip_area = 2.0*mem_area/(double)nmolbox;
-
- return mem_p->mem_at.nr;
-}
-
-void init_resize(t_block *ins_at,rvec *r_ins,pos_ins_t *pos_ins,mem_t *mem_p,rvec *r, gmx_bool bALLOW_ASYMMETRY)
-{
- int i,j,at,c,outsidesum,gctr=0;
- int idxsum=0;
-
- /*sanity check*/
- for (i=0;i<pos_ins->pieces;i++)
- idxsum+=pos_ins->nidx[i];
- if (idxsum!=ins_at->nr)
- gmx_fatal(FARGS,"Piecewise sum of inserted atoms not same as size of group selected to insert.");
-
- snew(pos_ins->geom_cent,pos_ins->pieces);
- for (i=0;i<pos_ins->pieces;i++)
- {
- c=0;
- outsidesum=0;
- for(j=0;j<DIM;j++)
- pos_ins->geom_cent[i][j]=0;
-
- for(j=0;j<DIM;j++)
- pos_ins->geom_cent[i][j]=0;
- for (j=0;j<pos_ins->nidx[i];j++)
- {
- at=pos_ins->subindex[i][j];
- copy_rvec(r[at],r_ins[gctr]);
- if( (r_ins[gctr][ZZ]<mem_p->zmax) && (r_ins[gctr][ZZ]>mem_p->zmin) )
- {
- rvec_inc(pos_ins->geom_cent[i],r_ins[gctr]);
- c++;
- }
- else
- outsidesum++;
- gctr++;
- }
- if (c>0)
- svmul(1/(double)c,pos_ins->geom_cent[i],pos_ins->geom_cent[i]);
- if (!bALLOW_ASYMMETRY)
- pos_ins->geom_cent[i][ZZ]=mem_p->zmed;
-
- fprintf(stderr,"Embedding piece %d with center of geometry: %f %f %f\n",i,pos_ins->geom_cent[i][XX],pos_ins->geom_cent[i][YY],pos_ins->geom_cent[i][ZZ]);
- }
- fprintf(stderr,"\n");
-}
-
-void resize(t_block *ins_at, rvec *r_ins, rvec *r, pos_ins_t *pos_ins,rvec fac)
-{
- int i,j,k,at,c=0;
- for (k=0;k<pos_ins->pieces;k++)
- for(i=0;i<pos_ins->nidx[k];i++)
- {
- at=pos_ins->subindex[k][i];
- for(j=0;j<DIM;j++)
- r[at][j]=pos_ins->geom_cent[k][j]+fac[j]*(r_ins[c][j]-pos_ins->geom_cent[k][j]);
- c++;
- }
-}
-
-int gen_rm_list(rm_t *rm_p,t_block *ins_at,t_block *rest_at,t_pbc *pbc, gmx_mtop_t *mtop,
- rvec *r, rvec *r_ins, mem_t *mem_p, pos_ins_t *pos_ins, real probe_rad, int low_up_rm, gmx_bool bALLOW_ASYMMETRY)
-{
- int i,j,k,l,at,at2,mol_id;
- int type=0,block=0;
- int nrm,nupper,nlower;
- real r_min_rad,z_lip,min_norm;
- gmx_bool bRM;
- rvec dr,dr_tmp;
- real *dist;
- int *order;
-
- r_min_rad=probe_rad*probe_rad;
- snew(rm_p->mol,mtop->mols.nr);
- snew(rm_p->block,mtop->mols.nr);
- nrm=nupper=0;
- nlower=low_up_rm;
- for(i=0;i<ins_at->nr;i++)
- {
- at=ins_at->index[i];
- for(j=0;j<rest_at->nr;j++)
- {
- at2=rest_at->index[j];
- pbc_dx(pbc,r[at],r[at2],dr);
-
- if(norm2(dr)<r_min_rad)
- {
- mol_id = get_mol_id(at2,mtop->nmolblock,mtop->molblock,&type,&block);
- bRM=TRUE;
- for(l=0;l<nrm;l++)
- if(rm_p->mol[l]==mol_id)
- bRM=FALSE;
- if(bRM)
- {
- /*fprintf(stderr,"%d wordt toegevoegd\n",mol_id);*/
- rm_p->mol[nrm]=mol_id;
- rm_p->block[nrm]=block;
- nrm++;
- z_lip=0.0;
- for(l=0;l<mem_p->nmol;l++)
- {
- if(mol_id==mem_p->mol_id[l])
- {
- for(k=mtop->mols.index[mol_id];k<mtop->mols.index[mol_id+1];k++)
- z_lip+=r[k][ZZ];
- z_lip/=mtop->molblock[block].natoms_mol;
- if(z_lip<mem_p->zmed)
- nlower++;
- else
- nupper++;
- }
- }
- }
- }
- }
- }
-
- /*make sure equal number of lipids from upper and lower layer are removed */
- if( (nupper!=nlower) && (!bALLOW_ASYMMETRY) )
- {
- snew(dist,mem_p->nmol);
- snew(order,mem_p->nmol);
- for(i=0;i<mem_p->nmol;i++)
- {
- at = mtop->mols.index[mem_p->mol_id[i]];
- pbc_dx(pbc,r[at],pos_ins->geom_cent[0],dr);
- if (pos_ins->pieces>1)
- {
- /*minimum dr value*/
- min_norm=norm2(dr);
- for (k=1;k<pos_ins->pieces;k++)
- {
- pbc_dx(pbc,r[at],pos_ins->geom_cent[k],dr_tmp);
- if (norm2(dr_tmp) < min_norm)
- {
- min_norm=norm2(dr_tmp);
- copy_rvec(dr_tmp,dr);
- }
- }
- }
- dist[i]=dr[XX]*dr[XX]+dr[YY]*dr[YY];
- j=i-1;
- while (j>=0 && dist[i]<dist[order[j]])
- {
- order[j+1]=order[j];
- j--;
- }
- order[j+1]=i;
- }
-
- i=0;
- while(nupper!=nlower)
- {
- mol_id=mem_p->mol_id[order[i]];
- block=get_block(mol_id,mtop->nmolblock,mtop->molblock);
-
- bRM=TRUE;
- for(l=0;l<nrm;l++)
- if(rm_p->mol[l]==mol_id)
- bRM=FALSE;
- if(bRM)
- {
- z_lip=0;
- for(k=mtop->mols.index[mol_id];k<mtop->mols.index[mol_id+1];k++)
- z_lip+=r[k][ZZ];
- z_lip/=mtop->molblock[block].natoms_mol;
- if(nupper>nlower && z_lip<mem_p->zmed)
- {
- rm_p->mol[nrm]=mol_id;
- rm_p->block[nrm]=block;
- nrm++;
- nlower++;
- }
- else if (nupper<nlower && z_lip>mem_p->zmed)
- {
- rm_p->mol[nrm]=mol_id;
- rm_p->block[nrm]=block;
- nrm++;
- nupper++;
- }
- }
- i++;
-
- if(i>mem_p->nmol)
- gmx_fatal(FARGS,"Trying to remove more lipid molecules than there are in the membrane");
- }
- sfree(dist);
- sfree(order);
- }
-
- rm_p->nr=nrm;
- srenew(rm_p->mol,nrm);
- srenew(rm_p->block,nrm);
-
- return nupper+nlower;
-}
-
-void rm_group(t_inputrec *ir, gmx_groups_t *groups, gmx_mtop_t *mtop, rm_t *rm_p, t_state *state, t_block *ins_at, pos_ins_t *pos_ins)
-{
- int i,j,k,n,rm,mol_id,at,block;
- rvec *x_tmp,*v_tmp;
- atom_id *list,*new_mols;
- unsigned char *new_egrp[egcNR];
- gmx_bool bRM;
-
- snew(list,state->natoms);
- n=0;
- for(i=0;i<rm_p->nr;i++)
- {
- mol_id=rm_p->mol[i];
- at=mtop->mols.index[mol_id];
- block =rm_p->block[i];
- mtop->molblock[block].nmol--;
- for(j=0;j<mtop->molblock[block].natoms_mol;j++)
- {
- list[n]=at+j;
- n++;
- }
-
- mtop->mols.index[mol_id]=-1;
- }
-
- mtop->mols.nr-=rm_p->nr;
- mtop->mols.nalloc_index-=rm_p->nr;
- snew(new_mols,mtop->mols.nr);
- for(i=0;i<mtop->mols.nr+rm_p->nr;i++)
- {
- j=0;
- if(mtop->mols.index[i]!=-1)
- {
- new_mols[j]=mtop->mols.index[i];
- j++;
- }
- }
- sfree(mtop->mols.index);
- mtop->mols.index=new_mols;
-
-
- mtop->natoms-=n;
- state->natoms-=n;
- state->nalloc=state->natoms;
- snew(x_tmp,state->nalloc);
- snew(v_tmp,state->nalloc);
-
- for(i=0;i<egcNR;i++)
- {
- if(groups->grpnr[i]!=NULL)
- {
- groups->ngrpnr[i]=state->natoms;
- snew(new_egrp[i],state->natoms);
- }
- }
-
- rm=0;
- for (i=0;i<state->natoms+n;i++)
- {
- bRM=FALSE;
- for(j=0;j<n;j++)
- {
- if(i==list[j])
- {
- bRM=TRUE;
- rm++;
- }
- }
-
- if(!bRM)
- {
- for(j=0;j<egcNR;j++)
- {
- if(groups->grpnr[j]!=NULL)
- {
- new_egrp[j][i-rm]=groups->grpnr[j][i];
- }
- }
- copy_rvec(state->x[i],x_tmp[i-rm]);
- copy_rvec(state->v[i],v_tmp[i-rm]);
- for(j=0;j<ins_at->nr;j++)
- {
- if (i==ins_at->index[j])
- ins_at->index[j]=i-rm;
- }
- for(j=0;j<pos_ins->pieces;j++)
- {
- for(k=0;k<pos_ins->nidx[j];k++)
- {
- if (i==pos_ins->subindex[j][k])
- pos_ins->subindex[j][k]=i-rm;
- }
- }
- }
- }
- sfree(state->x);
- state->x=x_tmp;
- sfree(state->v);
- state->v=v_tmp;
-
- for(i=0;i<egcNR;i++)
- {
- if(groups->grpnr[i]!=NULL)
- {
- sfree(groups->grpnr[i]);
- groups->grpnr[i]=new_egrp[i];
- }
- }
-}
-
-int rm_bonded(t_block *ins_at, gmx_mtop_t *mtop)
-{
- int i,j,m;
- int type,natom,nmol,at,atom1=0,rm_at=0;
- gmx_bool *bRM,bINS;
- /*this routine lives dangerously by assuming that all molecules of a given type are in order in the structure*/
- /*this routine does not live as dangerously as it seems. There is namely a check in mdrunner_membed to make
- *sure that g_membed exits with a warning when there are molecules of the same type not in the
- *ins_at index group. MGWolf 050710 */
-
-
- snew(bRM,mtop->nmoltype);
- for (i=0;i<mtop->nmoltype;i++)
- {
- bRM[i]=TRUE;
- }
-
- for (i=0;i<mtop->nmolblock;i++)
- {
- /*loop over molecule blocks*/
- type =mtop->molblock[i].type;
- natom =mtop->molblock[i].natoms_mol;
- nmol =mtop->molblock[i].nmol;
-
- for(j=0;j<natom*nmol && bRM[type]==TRUE;j++)
- {
- /*loop over atoms in the block*/
- at=j+atom1; /*atom index = block index + offset*/
- bINS=FALSE;
-
- for (m=0;(m<ins_at->nr) && (bINS==FALSE);m++)
- {
- /*loop over atoms in insertion index group to determine if we're inserting one*/
- if(at==ins_at->index[m])
- {
- bINS=TRUE;
- }
- }
- bRM[type]=bINS;
- }
- atom1+=natom*nmol; /*update offset*/
- if(bRM[type])
- {
- rm_at+=natom*nmol; /*increment bonded removal counter by # atoms in block*/
- }
- }
-
- for(i=0;i<mtop->nmoltype;i++)
- {
- if(bRM[i])
- {
- for(j=0;j<F_LJ;j++)
- {
- mtop->moltype[i].ilist[j].nr=0;
- }
- for(j=F_POSRES;j<=F_VSITEN;j++)
- {
- mtop->moltype[i].ilist[j].nr=0;
- }
- }
- }
- sfree(bRM);
-
- return rm_at;
-}
-
-void top_update(const char *topfile, char *ins, rm_t *rm_p, gmx_mtop_t *mtop)
-{
-#define TEMP_FILENM "temp.top"
- int bMolecules=0;
- FILE *fpin,*fpout;
- char buf[STRLEN],buf2[STRLEN],*temp;
- int i,*nmol_rm,nmol,line;
-
- fpin = ffopen(topfile,"r");
- fpout = ffopen(TEMP_FILENM,"w");
-
- snew(nmol_rm,mtop->nmoltype);
- for(i=0;i<rm_p->nr;i++)
- nmol_rm[rm_p->block[i]]++;
-
- line=0;
- while(fgets(buf,STRLEN,fpin))
- {
- line++;
- if(buf[0]!=';')
- {
- strcpy(buf2,buf);
- if ((temp=strchr(buf2,'\n')) != NULL)
- temp[0]='\0';
- ltrim(buf2);
-
- if (buf2[0]=='[')
- {
- buf2[0]=' ';
- if ((temp=strchr(buf2,'\n')) != NULL)
- temp[0]='\0';
- rtrim(buf2);
- if (buf2[strlen(buf2)-1]==']')
- {
- buf2[strlen(buf2)-1]='\0';
- ltrim(buf2);
- rtrim(buf2);
- if (gmx_strcasecmp(buf2,"molecules")==0)
- bMolecules=1;
- }
- fprintf(fpout,"%s",buf);
- } else if (bMolecules==1)
- {
- for(i=0;i<mtop->nmolblock;i++)
- {
- nmol=mtop->molblock[i].nmol;
- sprintf(buf,"%-15s %5d\n",*(mtop->moltype[mtop->molblock[i].type].name),nmol);
- fprintf(fpout,"%s",buf);
- }
- bMolecules=2;
- } else if (bMolecules==2)
- {
- /* print nothing */
- } else
- {
- fprintf(fpout,"%s",buf);
- }
- } else
- {
- fprintf(fpout,"%s",buf);
- }
- }
-
- fclose(fpout);
- /* use ffopen to generate backup of topinout */
- fpout=ffopen(topfile,"w");
- fclose(fpout);
- rename(TEMP_FILENM,topfile);
-#undef TEMP_FILENM
-}
-
-void md_print_warning(const t_commrec *cr,FILE *fplog,const char *buf)
-{
- if (MASTER(cr))
- {
- fprintf(stderr,"\n%s\n",buf);
- }
- if (fplog)
- {
- fprintf(fplog,"\n%s\n",buf);
- }
-}
-
-/* simulation conditions to transmit. Keep in mind that they are
- transmitted to other nodes through an MPI_Reduce after
- casting them to a real (so the signals can be sent together with other
- data). This means that the only meaningful values are positive,
- negative or zero. */
-enum { eglsNABNSB, eglsCHKPT, eglsSTOPCOND, eglsRESETCOUNTERS, eglsNR };
-/* Is the signal in one simulation independent of other simulations? */
-gmx_bool gs_simlocal[eglsNR] = { TRUE, FALSE, FALSE, TRUE };
-
-typedef struct {
- int nstms; /* The frequency for intersimulation communication */
- int sig[eglsNR]; /* The signal set by one process in do_md */
- int set[eglsNR]; /* The communicated signal, equal for all processes */
-} globsig_t;
-
-
-static int multisim_min(const gmx_multisim_t *ms,int nmin,int n)
-{
- int *buf;
- gmx_bool bPos,bEqual;
- int s,d;
-
- snew(buf,ms->nsim);
- buf[ms->sim] = n;
- gmx_sumi_sim(ms->nsim,buf,ms);
- bPos = TRUE;
- bEqual = TRUE;
- for(s=0; s<ms->nsim; s++)
- {
- bPos = bPos && (buf[s] > 0);
- bEqual = bEqual && (buf[s] == buf[0]);
- }
- if (bPos)
- {
- if (bEqual)
- {
- nmin = min(nmin,buf[0]);
- }
- else
- {
- /* Find the least common multiple */
- for(d=2; d<nmin; d++)
- {
- s = 0;
- while (s < ms->nsim && d % buf[s] == 0)
- {
- s++;
- }
- if (s == ms->nsim)
- {
- /* We found the LCM and it is less than nmin */
- nmin = d;
- break;
- }
- }
- }
- }
- sfree(buf);
-
- return nmin;
-}
-
-static int multisim_nstsimsync(const t_commrec *cr,
- const t_inputrec *ir,int repl_ex_nst)
-{
- int nmin;
-
- if (MASTER(cr))
- {
- nmin = INT_MAX;
- nmin = multisim_min(cr->ms,nmin,ir->nstlist);
- nmin = multisim_min(cr->ms,nmin,ir->nstcalcenergy);
- nmin = multisim_min(cr->ms,nmin,repl_ex_nst);
- if (nmin == INT_MAX)
- {
- gmx_fatal(FARGS,"Can not find an appropriate interval for inter-simulation communication, since nstlist, nstcalcenergy and -replex are all <= 0");
- }
- /* Avoid inter-simulation communication at every (second) step */
- if (nmin <= 2)
- {
- nmin = 10;
- }
- }
-
- gmx_bcast(sizeof(int),&nmin,cr);
-
- return nmin;
-}
-
-static void init_global_signals(globsig_t *gs,const t_commrec *cr,
- const t_inputrec *ir,int repl_ex_nst)
-{
- int i;
-
- if (MULTISIM(cr))
- {
- gs->nstms = multisim_nstsimsync(cr,ir,repl_ex_nst);
- if (debug)
- {
- fprintf(debug,"Syncing simulations for checkpointing and termination every %d steps\n",gs->nstms);
- }
- }
- else
- {
- gs->nstms = 1;
- }
-
- for(i=0; i<eglsNR; i++)
- {
- gs->sig[i] = 0;
- gs->set[i] = 0;
- }
-}
-
-static void copy_coupling_state(t_state *statea,t_state *stateb,
- gmx_ekindata_t *ekinda,gmx_ekindata_t *ekindb, t_grpopts* opts)
-{
-
- /* MRS note -- might be able to get rid of some of the arguments. Look over it when it's all debugged */
-
- int i,j,nc;
-
- /* Make sure we have enough space for x and v */
- if (statea->nalloc > stateb->nalloc)
- {
- stateb->nalloc = statea->nalloc;
- srenew(stateb->x,stateb->nalloc);
- srenew(stateb->v,stateb->nalloc);
- }
-
- stateb->natoms = statea->natoms;
- stateb->ngtc = statea->ngtc;
- stateb->nnhpres = statea->nnhpres;
- stateb->veta = statea->veta;
- if (ekinda)
- {
- copy_mat(ekinda->ekin,ekindb->ekin);
- for (i=0; i<stateb->ngtc; i++)
- {
- ekindb->tcstat[i].T = ekinda->tcstat[i].T;
- ekindb->tcstat[i].Th = ekinda->tcstat[i].Th;
- copy_mat(ekinda->tcstat[i].ekinh,ekindb->tcstat[i].ekinh);
- copy_mat(ekinda->tcstat[i].ekinf,ekindb->tcstat[i].ekinf);
- ekindb->tcstat[i].ekinscalef_nhc = ekinda->tcstat[i].ekinscalef_nhc;
- ekindb->tcstat[i].ekinscaleh_nhc = ekinda->tcstat[i].ekinscaleh_nhc;
- ekindb->tcstat[i].vscale_nhc = ekinda->tcstat[i].vscale_nhc;
- }
- }
- copy_rvecn(statea->x,stateb->x,0,stateb->natoms);
- copy_rvecn(statea->v,stateb->v,0,stateb->natoms);
- copy_mat(statea->box,stateb->box);
- copy_mat(statea->box_rel,stateb->box_rel);
- copy_mat(statea->boxv,stateb->boxv);
-
- for (i = 0; i<stateb->ngtc; i++)
- {
- nc = i*opts->nhchainlength;
- for (j=0; j<opts->nhchainlength; j++)
- {
- stateb->nosehoover_xi[nc+j] = statea->nosehoover_xi[nc+j];
- stateb->nosehoover_vxi[nc+j] = statea->nosehoover_vxi[nc+j];
- }
- }
- if (stateb->nhpres_xi != NULL)
- {
- for (i = 0; i<stateb->nnhpres; i++)
- {
- nc = i*opts->nhchainlength;
- for (j=0; j<opts->nhchainlength; j++)
- {
- stateb->nhpres_xi[nc+j] = statea->nhpres_xi[nc+j];
- stateb->nhpres_vxi[nc+j] = statea->nhpres_vxi[nc+j];
- }
- }
- }
-}
-
-static void compute_globals(FILE *fplog, gmx_global_stat_t gstat, t_commrec *cr, t_inputrec *ir,
- t_forcerec *fr, gmx_ekindata_t *ekind,
- t_state *state, t_state *state_global, t_mdatoms *mdatoms,
- t_nrnb *nrnb, t_vcm *vcm, gmx_wallcycle_t wcycle,
- gmx_enerdata_t *enerd,tensor force_vir, tensor shake_vir, tensor total_vir,
- tensor pres, rvec mu_tot, gmx_constr_t constr,
- globsig_t *gs,gmx_bool bInterSimGS,
- matrix box, gmx_mtop_t *top_global, real *pcurr,
- int natoms, gmx_bool *bSumEkinhOld, int flags)
-{
- int i,gsi;
- real gs_buf[eglsNR];
- tensor corr_vir,corr_pres;
- gmx_bool bEner,bPres,bTemp;
- gmx_bool bRerunMD, bStopCM, bGStat, bIterate,
- bFirstIterate,bReadEkin,bEkinAveVel,bScaleEkin, bConstrain;
- real prescorr,enercorr,dvdlcorr;
-
- /* translate CGLO flags to gmx_booleans */
- bRerunMD = flags & CGLO_RERUNMD;
- bStopCM = flags & CGLO_STOPCM;
- bGStat = flags & CGLO_GSTAT;
- bReadEkin = (flags & CGLO_READEKIN);
- bScaleEkin = (flags & CGLO_SCALEEKIN);
- bEner = flags & CGLO_ENERGY;
- bTemp = flags & CGLO_TEMPERATURE;
- bPres = (flags & CGLO_PRESSURE);
- bConstrain = (flags & CGLO_CONSTRAINT);
- bIterate = (flags & CGLO_ITERATE);
- bFirstIterate = (flags & CGLO_FIRSTITERATE);
-
- /* we calculate a full state kinetic energy either with full-step velocity verlet
- or half step where we need the pressure */
- bEkinAveVel = (ir->eI==eiVV || (ir->eI==eiVVAK && IR_NPT_TROTTER(ir) && bPres) || bReadEkin);
-
- /* in initalization, it sums the shake virial in vv, and to
- sums ekinh_old in leapfrog (or if we are calculating ekinh_old for other reasons */
-
- /* ########## Kinetic energy ############## */
-
- if (bTemp)
- {
- /* Non-equilibrium MD: this is parallellized, but only does communication
- * when there really is NEMD.
- */
-
- if (PAR(cr) && (ekind->bNEMD))
- {
- accumulate_u(cr,&(ir->opts),ekind);
- }
- debug_gmx();
- if (bReadEkin)
- {
- restore_ekinstate_from_state(cr,ekind,&state_global->ekinstate);
- }
- else
- {
-
- calc_ke_part(state,&(ir->opts),mdatoms,ekind,nrnb,bEkinAveVel,bIterate);
- }
-
- debug_gmx();
-
- /* Calculate center of mass velocity if necessary, also parallellized */
- if (bStopCM && !bRerunMD && bEner)
- {
- calc_vcm_grp(fplog,mdatoms->start,mdatoms->homenr,mdatoms,
- state->x,state->v,vcm);
- }
- }
-
- if (bTemp || bPres || bEner || bConstrain)
- {
- if (!bGStat)
- {
- /* We will not sum ekinh_old,
- * so signal that we still have to do it.
- */
- *bSumEkinhOld = TRUE;
-
- }
- else
- {
- if (gs != NULL)
- {
- for(i=0; i<eglsNR; i++)
- {
- gs_buf[i] = gs->sig[i];
- }
- }
- if (PAR(cr))
- {
- wallcycle_start(wcycle,ewcMoveE);
- GMX_MPE_LOG(ev_global_stat_start);
- global_stat(fplog,gstat,cr,enerd,force_vir,shake_vir,mu_tot,
- ir,ekind,constr,vcm,
- gs != NULL ? eglsNR : 0,gs_buf,
- top_global,state,
- *bSumEkinhOld,flags);
- GMX_MPE_LOG(ev_global_stat_finish);
- wallcycle_stop(wcycle,ewcMoveE);
- }
- if (gs != NULL)
- {
- if (MULTISIM(cr) && bInterSimGS)
- {
- if (MASTER(cr))
- {
- /* Communicate the signals between the simulations */
- gmx_sum_sim(eglsNR,gs_buf,cr->ms);
- }
- /* Communicate the signals form the master to the others */
- gmx_bcast(eglsNR*sizeof(gs_buf[0]),gs_buf,cr);
- }
- for(i=0; i<eglsNR; i++)
- {
- if (bInterSimGS || gs_simlocal[i])
- {
- /* Set the communicated signal only when it is non-zero,
- * since signals might not be processed at each MD step.
- */
- gsi = (gs_buf[i] >= 0 ?
- (int)(gs_buf[i] + 0.5) :
- (int)(gs_buf[i] - 0.5));
- if (gsi != 0)
- {
- gs->set[i] = gsi;
- }
- /* Turn off the local signal */
- gs->sig[i] = 0;
- }
- }
- }
- *bSumEkinhOld = FALSE;
- }
- }
-
- if (!ekind->bNEMD && debug && bTemp && (vcm->nr > 0))
- {
- correct_ekin(debug,
- mdatoms->start,mdatoms->start+mdatoms->homenr,
- state->v,vcm->group_p[0],
- mdatoms->massT,mdatoms->tmass,ekind->ekin);
- }
-
- if (bEner) {
- /* Do center of mass motion removal */
- if (bStopCM && !bRerunMD) /* is this correct? Does it get called too often with this logic? */
- {
- check_cm_grp(fplog,vcm,ir,1);
- do_stopcm_grp(fplog,mdatoms->start,mdatoms->homenr,mdatoms->cVCM,
- state->x,state->v,vcm);
- inc_nrnb(nrnb,eNR_STOPCM,mdatoms->homenr);
- }
- }
-
- if (bTemp)
- {
- /* Sum the kinetic energies of the groups & calc temp */
- /* compute full step kinetic energies if vv, or if vv-avek and we are computing the pressure with IR_NPT_TROTTER */
- /* three maincase: VV with AveVel (md-vv), vv with AveEkin (md-vv-avek), leap with AveEkin (md).
- Leap with AveVel is also an option for the future but not supported now.
- bEkinAveVel: If TRUE, we simply multiply ekin by ekinscale to get a full step kinetic energy.
- If FALSE, we average ekinh_old and ekinh*ekinscale_nhc to get an averaged half step kinetic energy.
- bSaveEkinOld: If TRUE (in the case of iteration = bIterate is TRUE), we don't reset the ekinscale_nhc.
- If FALSE, we go ahead and erase over it.
- */
- enerd->term[F_TEMP] = sum_ekin(&(ir->opts),ekind,&(enerd->term[F_DKDL]),
- bEkinAveVel,bIterate,bScaleEkin);
-
- enerd->term[F_EKIN] = trace(ekind->ekin);
- }
-
- /* ########## Long range energy information ###### */
-
- if (bEner || bPres || bConstrain)
- {
- calc_dispcorr(fplog,ir,fr,0,top_global->natoms,box,state->lambda,
- corr_pres,corr_vir,&prescorr,&enercorr,&dvdlcorr);
- }
-
- if (bEner && bFirstIterate)
- {
- enerd->term[F_DISPCORR] = enercorr;
- enerd->term[F_EPOT] += enercorr;
- enerd->term[F_DVDL] += dvdlcorr;
- if (fr->efep != efepNO) {
- enerd->dvdl_lin += dvdlcorr;
- }
- }
-
- /* ########## Now pressure ############## */
- if (bPres || bConstrain)
- {
-
- m_add(force_vir,shake_vir,total_vir);
-
- /* Calculate pressure and apply LR correction if PPPM is used.
- * Use the box from last timestep since we already called update().
- */
-
- enerd->term[F_PRES] = calc_pres(fr->ePBC,ir->nwall,box,ekind->ekin,total_vir,pres,
- (fr->eeltype==eelPPPM)?enerd->term[F_COUL_RECIP]:0.0);
-
- /* Calculate long range corrections to pressure and energy */
- /* this adds to enerd->term[F_PRES] and enerd->term[F_ETOT],
- and computes enerd->term[F_DISPCORR]. Also modifies the
- total_vir and pres tesors */
-
- m_add(total_vir,corr_vir,total_vir);
- m_add(pres,corr_pres,pres);
- enerd->term[F_PDISPCORR] = prescorr;
- enerd->term[F_PRES] += prescorr;
- *pcurr = enerd->term[F_PRES];
- /* calculate temperature using virial */
- enerd->term[F_VTEMP] = calc_temp(trace(total_vir),ir->opts.nrdf[0]);
-
- }
-}
-
-
-/* Definitions for convergence of iterated constraints */
-
-/* iterate constraints up to 50 times */
-#define MAXITERCONST 50
-
-/* data type */
-typedef struct
-{
- real f,fprev,x,xprev;
- int iter_i;
- gmx_bool bIterate;
- real allrelerr[MAXITERCONST+2];
- int num_close; /* number of "close" violations, caused by limited precision. */
-} gmx_iterate_t;
-
-#ifdef GMX_DOUBLE
-#define CONVERGEITER 0.000000001
-#define CLOSE_ENOUGH 0.000001000
-#else
-#define CONVERGEITER 0.0001
-#define CLOSE_ENOUGH 0.0050
-#endif
-
-/* we want to keep track of the close calls. If there are too many, there might be some other issues.
- so we make sure that it's either less than some predetermined number, or if more than that number,
- only some small fraction of the total. */
-#define MAX_NUMBER_CLOSE 50
-#define FRACTION_CLOSE 0.001
-
-/* maximum length of cyclic traps to check, emerging from limited numerical precision */
-#define CYCLEMAX 20
-
-static void gmx_iterate_init(gmx_iterate_t *iterate,gmx_bool bIterate)
-{
- int i;
-
- iterate->iter_i = 0;
- iterate->bIterate = bIterate;
- iterate->num_close = 0;
- for (i=0;i<MAXITERCONST+2;i++)
- {
- iterate->allrelerr[i] = 0;
- }
-}
-
-static gmx_bool done_iterating(const t_commrec *cr,FILE *fplog, int nsteps, gmx_iterate_t *iterate, gmx_bool bFirstIterate, real fom, real *newf)
-{
- /* monitor convergence, and use a secant search to propose new
- values.
- x_{i} - x_{i-1}
- The secant method computes x_{i+1} = x_{i} - f(x_{i}) * ---------------------
- f(x_{i}) - f(x_{i-1})
-
- The function we are trying to zero is fom-x, where fom is the
- "figure of merit" which is the pressure (or the veta value) we
- would get by putting in an old value of the pressure or veta into
- the incrementor function for the step or half step. I have
- verified that this gives the same answer as self consistent
- iteration, usually in many fewer steps, especially for small tau_p.
-
- We could possibly eliminate an iteration with proper use
- of the value from the previous step, but that would take a bit
- more bookkeeping, especially for veta, since tests indicate the
- function of veta on the last step is not sufficiently close to
- guarantee convergence this step. This is
- good enough for now. On my tests, I could use tau_p down to
- 0.02, which is smaller that would ever be necessary in
- practice. Generally, 3-5 iterations will be sufficient */
-
- real relerr,err;
- char buf[256];
- int i;
- gmx_bool incycle;
-
- if (bFirstIterate)
- {
- iterate->x = fom;
- iterate->f = fom-iterate->x;
- iterate->xprev = 0;
- iterate->fprev = 0;
- *newf = fom;
- }
- else
- {
- iterate->f = fom-iterate->x; /* we want to zero this difference */
- if ((iterate->iter_i > 1) && (iterate->iter_i < MAXITERCONST))
- {
- if (iterate->f==iterate->fprev)
- {
- *newf = iterate->f;
- }
- else
- {
- *newf = iterate->x - (iterate->x-iterate->xprev)*(iterate->f)/(iterate->f-iterate->fprev);
- }
- }
- else
- {
- /* just use self-consistent iteration the first step to initialize, or
- if it's not converging (which happens occasionally -- need to investigate why) */
- *newf = fom;
- }
- }
- /* Consider a slight shortcut allowing us to exit one sooner -- we check the
- difference between the closest of x and xprev to the new
- value. To be 100% certain, we should check the difference between
- the last result, and the previous result, or
-
- relerr = (fabs((x-xprev)/fom));
-
- but this is pretty much never necessary under typical conditions.
- Checking numerically, it seems to lead to almost exactly the same
- trajectories, but there are small differences out a few decimal
- places in the pressure, and eventually in the v_eta, but it could
- save an interation.
-
- if (fabs(*newf-x) < fabs(*newf - xprev)) { xmin = x;} else { xmin = xprev;}
- relerr = (fabs((*newf-xmin) / *newf));
- */
-
- err = fabs((iterate->f-iterate->fprev));
- relerr = fabs(err/fom);
-
- iterate->allrelerr[iterate->iter_i] = relerr;
-
- if (iterate->iter_i > 0)
- {
- if (debug)
- {
- fprintf(debug,"Iterating NPT constraints: %6i %20.12f%14.6g%20.12f\n",
- iterate->iter_i,fom,relerr,*newf);
- }
-
- if ((relerr < CONVERGEITER) || (err < CONVERGEITER) || (fom==0) || ((iterate->x == iterate->xprev) && iterate->iter_i > 1))
- {
- iterate->bIterate = FALSE;
- if (debug)
- {
- fprintf(debug,"Iterating NPT constraints: CONVERGED\n");
- }
- return TRUE;
- }
- if (iterate->iter_i > MAXITERCONST)
- {
- if (relerr < CLOSE_ENOUGH)
- {
- incycle = FALSE;
- for (i=1;i<CYCLEMAX;i++) {
- if ((iterate->allrelerr[iterate->iter_i-(1+i)] == iterate->allrelerr[iterate->iter_i-1]) &&
- (iterate->allrelerr[iterate->iter_i-(1+i)] == iterate->allrelerr[iterate->iter_i-(1+2*i)])) {
- incycle = TRUE;
- if (debug)
- {
- fprintf(debug,"Exiting from an NPT iterating cycle of length %d\n",i);
- }
- break;
- }
- }
-
- if (incycle) {
- /* step 1: trapped in a numerical attractor */
- /* we are trapped in a numerical attractor, and can't converge any more, and are close to the final result.
- Better to give up convergence here than have the simulation die.
- */
- iterate->num_close++;
- return TRUE;
- }
- else
- {
- /* Step #2: test if we are reasonably close for other reasons, then monitor the number. If not, die */
-
- /* how many close calls have we had? If less than a few, we're OK */
- if (iterate->num_close < MAX_NUMBER_CLOSE)
- {
- sprintf(buf,"Slight numerical convergence deviation with NPT at step %d, relative error only %10.5g, likely not a problem, continuing\n",nsteps,relerr);
- md_print_warning(cr,fplog,buf);
- iterate->num_close++;
- return TRUE;
- /* if more than a few, check the total fraction. If too high, die. */
- } else if (iterate->num_close/(double)nsteps > FRACTION_CLOSE) {
- gmx_fatal(FARGS,"Could not converge NPT constraints, too many exceptions (%d%%\n",iterate->num_close/(double)nsteps);
- }
- }
- }
- else
- {
- gmx_fatal(FARGS,"Could not converge NPT constraints\n");
- }
- }
- }
-
- iterate->xprev = iterate->x;
- iterate->x = *newf;
- iterate->fprev = iterate->f;
- iterate->iter_i++;
-
- return FALSE;
-}
-
-static void check_nst_param(FILE *fplog,t_commrec *cr,
- const char *desc_nst,int nst,
- const char *desc_p,int *p)
-{
- char buf[STRLEN];
-
- if (*p > 0 && *p % nst != 0)
- {
- /* Round up to the next multiple of nst */
- *p = ((*p)/nst + 1)*nst;
- sprintf(buf,"NOTE: %s changes %s to %d\n",desc_nst,desc_p,*p);
- md_print_warning(cr,fplog,buf);
- }
-}
-
-static void reset_all_counters(FILE *fplog,t_commrec *cr,
- gmx_large_int_t step,
- gmx_large_int_t *step_rel,t_inputrec *ir,
- gmx_wallcycle_t wcycle,t_nrnb *nrnb,
- gmx_runtime_t *runtime)
-{
- char buf[STRLEN],sbuf[STEPSTRSIZE];
-
- /* Reset all the counters related to performance over the run */
- sprintf(buf,"Step %s: resetting all time and cycle counters\n",
- gmx_step_str(step,sbuf));
- md_print_warning(cr,fplog,buf);
-
- wallcycle_stop(wcycle,ewcRUN);
- wallcycle_reset_all(wcycle);
- if (DOMAINDECOMP(cr))
- {
- reset_dd_statistics_counters(cr->dd);
- }
- init_nrnb(nrnb);
- ir->init_step += *step_rel;
- ir->nsteps -= *step_rel;
- *step_rel = 0;
- wallcycle_start(wcycle,ewcRUN);
- runtime_start(runtime);
- print_date_and_time(fplog,cr->nodeid,"Restarted time",runtime);
-}
-
-static int check_nstglobalcomm(FILE *fplog,t_commrec *cr,
- int nstglobalcomm,t_inputrec *ir)
-{
- char buf[STRLEN];
-
- if (!EI_DYNAMICS(ir->eI))
- {
- nstglobalcomm = 1;
- }
-
- if (nstglobalcomm == -1)
- {
- if (ir->nstcalcenergy == 0 && ir->nstlist == 0)
- {
- nstglobalcomm = 10;
- if (ir->nstenergy > 0 && ir->nstenergy < nstglobalcomm)
- {
- nstglobalcomm = ir->nstenergy;
- }
- }
- else
- {
- /* We assume that if nstcalcenergy > nstlist,
- * nstcalcenergy is a multiple of nstlist.
- */
- if (ir->nstcalcenergy == 0 ||
- (ir->nstlist > 0 && ir->nstlist < ir->nstcalcenergy))
- {
- nstglobalcomm = ir->nstlist;
- }
- else
- {
- nstglobalcomm = ir->nstcalcenergy;
- }
- }
- }
- else
- {
- if (ir->nstlist > 0 &&
- nstglobalcomm > ir->nstlist && nstglobalcomm % ir->nstlist != 0)
- {
- nstglobalcomm = (nstglobalcomm / ir->nstlist)*ir->nstlist;
- sprintf(buf,"WARNING: nstglobalcomm is larger than nstlist, but not a multiple, setting it to %d\n",nstglobalcomm);
- md_print_warning(cr,fplog,buf);
- }
- if (nstglobalcomm > ir->nstcalcenergy)
- {
- check_nst_param(fplog,cr,"-gcom",nstglobalcomm,
- "nstcalcenergy",&ir->nstcalcenergy);
- }
-
- check_nst_param(fplog,cr,"-gcom",nstglobalcomm,
- "nstenergy",&ir->nstenergy);
-
- check_nst_param(fplog,cr,"-gcom",nstglobalcomm,
- "nstlog",&ir->nstlog);
- }
-
- if (ir->comm_mode != ecmNO && ir->nstcomm < nstglobalcomm)
- {
- sprintf(buf,"WARNING: Changing nstcomm from %d to %d\n",
- ir->nstcomm,nstglobalcomm);
- md_print_warning(cr,fplog,buf);
- ir->nstcomm = nstglobalcomm;
- }
-
- return nstglobalcomm;
-}
-
-void check_ir_old_tpx_versions(t_commrec *cr,FILE *fplog,
- t_inputrec *ir,gmx_mtop_t *mtop)
-{
- /* Check required for old tpx files */
- if (IR_TWINRANGE(*ir) && ir->nstlist > 1 &&
- ir->nstcalcenergy % ir->nstlist != 0)
- {
- md_print_warning(cr,fplog,"Old tpr file with twin-range settings: modifying energy calculation and/or T/P-coupling frequencies");
-
- if (gmx_mtop_ftype_count(mtop,F_CONSTR) +
- gmx_mtop_ftype_count(mtop,F_CONSTRNC) > 0 &&
- ir->eConstrAlg == econtSHAKE)
- {
- md_print_warning(cr,fplog,"With twin-range cut-off's and SHAKE the virial and pressure are incorrect");
- if (ir->epc != epcNO)
- {
- gmx_fatal(FARGS,"Can not do pressure coupling with twin-range cut-off's and SHAKE");
- }
- }
- check_nst_param(fplog,cr,"nstlist",ir->nstlist,
- "nstcalcenergy",&ir->nstcalcenergy);
- check_nst_param(fplog,cr,"nstcalcenergy",ir->nstcalcenergy,
- "nstenergy",&ir->nstenergy);
- check_nst_param(fplog,cr,"nstcalcenergy",ir->nstcalcenergy,
- "nstlog",&ir->nstlog);
- if (ir->efep != efepNO)
- {
- check_nst_param(fplog,cr,"nstcalcenergy",ir->nstcalcenergy,
- "nstdhdl",&ir->nstdhdl);
- }
- }
-}
-
-typedef struct {
- gmx_bool bGStatEveryStep;
- gmx_large_int_t step_ns;
- gmx_large_int_t step_nscheck;
- gmx_large_int_t nns;
- matrix scale_tot;
- int nabnsb;
- double s1;
- double s2;
- double ab;
- double lt_runav;
- double lt_runav2;
-} gmx_nlheur_t;
-
-static void reset_nlistheuristics(gmx_nlheur_t *nlh,gmx_large_int_t step)
-{
- nlh->lt_runav = 0;
- nlh->lt_runav2 = 0;
- nlh->step_nscheck = step;
-}
-
-static void init_nlistheuristics(gmx_nlheur_t *nlh,
- gmx_bool bGStatEveryStep,gmx_large_int_t step)
-{
- nlh->bGStatEveryStep = bGStatEveryStep;
- nlh->nns = 0;
- nlh->nabnsb = 0;
- nlh->s1 = 0;
- nlh->s2 = 0;
- nlh->ab = 0;
-
- reset_nlistheuristics(nlh,step);
-}
-
-static void update_nliststatistics(gmx_nlheur_t *nlh,gmx_large_int_t step)
-{
- gmx_large_int_t nl_lt;
- char sbuf[STEPSTRSIZE],sbuf2[STEPSTRSIZE];
-
- /* Determine the neighbor list life time */
- nl_lt = step - nlh->step_ns;
- if (debug)
- {
- fprintf(debug,"%d atoms beyond ns buffer, updating neighbor list after %s steps\n",nlh->nabnsb,gmx_step_str(nl_lt,sbuf));
- }
- nlh->nns++;
- nlh->s1 += nl_lt;
- nlh->s2 += nl_lt*nl_lt;
- nlh->ab += nlh->nabnsb;
- if (nlh->lt_runav == 0)
- {
- nlh->lt_runav = nl_lt;
- /* Initialize the fluctuation average
- * such that at startup we check after 0 steps.
- */
- nlh->lt_runav2 = sqr(nl_lt/2.0);
- }
- /* Running average with 0.9 gives an exp. history of 9.5 */
- nlh->lt_runav2 = 0.9*nlh->lt_runav2 + 0.1*sqr(nlh->lt_runav - nl_lt);
- nlh->lt_runav = 0.9*nlh->lt_runav + 0.1*nl_lt;
- if (nlh->bGStatEveryStep)
- {
- /* Always check the nlist validity */
- nlh->step_nscheck = step;
- }
- else
- {
- /* We check after: <life time> - 2*sigma
- * The factor 2 is quite conservative,
- * but we assume that with nstlist=-1 the user
- * prefers exact integration over performance.
- */
- nlh->step_nscheck = step
- + (int)(nlh->lt_runav - 2.0*sqrt(nlh->lt_runav2)) - 1;
- }
- if (debug)
- {
- fprintf(debug,"nlist life time %s run av. %4.1f sig %3.1f check %s check with -gcom %d\n",
- gmx_step_str(nl_lt,sbuf),nlh->lt_runav,sqrt(nlh->lt_runav2),
- gmx_step_str(nlh->step_nscheck-step+1,sbuf2),
- (int)(nlh->lt_runav - 2.0*sqrt(nlh->lt_runav2)));
- }
-}
-
-static void set_nlistheuristics(gmx_nlheur_t *nlh,gmx_bool bReset,gmx_large_int_t step)
-{
- int d;
-
- if (bReset)
- {
- reset_nlistheuristics(nlh,step);
- }
- else
- {
- update_nliststatistics(nlh,step);
- }
-
- nlh->step_ns = step;
- /* Initialize the cumulative coordinate scaling matrix */
- clear_mat(nlh->scale_tot);
- for(d=0; d<DIM; d++)
- {
- nlh->scale_tot[d][d] = 1.0;
- }
-}
-
-double do_md_membed(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_seed,
- real cpt_period,real max_hours,
- const char *deviceOptions,
- unsigned long Flags,
- gmx_runtime_t *runtime,
- rvec fac, rvec *r_ins, pos_ins_t *pos_ins, t_block *ins_at,
- real xy_step, real z_step, int it_xy, int it_z)
-{
- gmx_mdoutf_t *outf;
- gmx_large_int_t step,step_rel;
- double run_time;
- double t,t0,lam0;
- gmx_bool bGStatEveryStep,bGStat,bNstEner,bCalcEnerPres;
- gmx_bool bNS,bNStList,bSimAnn,bStopCM,bRerunMD,bNotLastFrame=FALSE,
- bFirstStep,bStateFromTPX,bInitStep,bLastStep,
- bBornRadii,bStartingFromCpt;
- gmx_bool bDoDHDL=FALSE;
- gmx_bool do_ene,do_log,do_verbose,bRerunWarnNoV=TRUE,
- bForceUpdate=FALSE,bCPT;
- int mdof_flags;
- gmx_bool bMasterState;
- int force_flags,cglo_flags;
- tensor force_vir,shake_vir,total_vir,tmp_vir,pres;
- int i,m;
- t_trxstatus *status;
- rvec mu_tot;
- t_vcm *vcm;
- t_state *bufstate=NULL;
- matrix *scale_tot,pcoupl_mu,M,ebox;
- gmx_nlheur_t nlh;
- t_trxframe rerun_fr;
-/* gmx_repl_ex_t repl_ex=NULL;*/
- int nchkpt=1;
-
- gmx_localtop_t *top;
- t_mdebin *mdebin=NULL;
- t_state *state=NULL;
- rvec *f_global=NULL;
- int n_xtc=-1;
- rvec *x_xtc=NULL;
- gmx_enerdata_t *enerd;
- rvec *f=NULL;
- gmx_global_stat_t gstat;
- gmx_update_t upd=NULL;
- t_graph *graph=NULL;
- globsig_t gs;
-
- gmx_bool bFFscan;
- gmx_groups_t *groups;
- gmx_ekindata_t *ekind, *ekind_save;
- gmx_shellfc_t shellfc;
- int count,nconverged=0;
- real timestep=0;
- double tcount=0;
- gmx_bool bIonize=FALSE;
- gmx_bool bTCR=FALSE,bConverged=TRUE,bOK,bSumEkinhOld,bExchanged;
- gmx_bool bAppend;
- gmx_bool bResetCountersHalfMaxH=FALSE;
- gmx_bool bVV,bIterations,bIterate,bFirstIterate,bTemp,bPres,bTrotter;
- real temp0,dvdl;
- int a0,a1,ii;
- rvec *xcopy=NULL,*vcopy=NULL,*cbuf=NULL;
- matrix boxcopy={{0}},lastbox;
- real veta_save,pcurr,scalevir,tracevir;
- real vetanew = 0;
- double cycles;
- real last_conserved = 0;
- real last_ekin = 0;
- t_extmass MassQ;
- int **trotter_seq;
- char sbuf[STEPSTRSIZE],sbuf2[STEPSTRSIZE];
- int handled_stop_condition=gmx_stop_cond_none; /* compare to get_stop_condition*/
- gmx_iterate_t iterate;
-#ifdef GMX_FAHCORE
- /* Temporary addition for FAHCORE checkpointing */
- int chkpt_ret;
-#endif
-
- /* Check for special mdrun options */
- bRerunMD = (Flags & MD_RERUN);
- bIonize = (Flags & MD_IONIZE);
- bFFscan = (Flags & MD_FFSCAN);
- bAppend = (Flags & MD_APPENDFILES);
- bGStatEveryStep = FALSE;
- if (Flags & MD_RESETCOUNTERSHALFWAY)
- {
- if (ir->nsteps > 0)
- {
- /* Signal to reset the counters half the simulation steps. */
- wcycle_set_reset_counters(wcycle,ir->nsteps/2);
- }
- /* Signal to reset the counters halfway the simulation time. */
- bResetCountersHalfMaxH = (max_hours > 0);
- }
-
- /* md-vv uses averaged full step velocities for T-control
- md-vv-avek uses averaged half step velocities for T-control (but full step ekin for P control)
- md uses averaged half step kinetic energies to determine temperature unless defined otherwise by GMX_EKIN_AVE_VEL; */
- bVV = EI_VV(ir->eI);
- if (bVV) /* to store the initial velocities while computing virial */
- {
- snew(cbuf,top_global->natoms);
- }
- /* all the iteratative cases - only if there are constraints */
- bIterations = ((IR_NPT_TROTTER(ir)) && (constr) && (!bRerunMD));
- bTrotter = (bVV && (IR_NPT_TROTTER(ir) || (IR_NVT_TROTTER(ir))));
-
- if (bRerunMD)
- {
- /* Since we don't know if the frames read are related in any way,
- * rebuild the neighborlist at every step.
- */
- ir->nstlist = 1;
- ir->nstcalcenergy = 1;
- nstglobalcomm = 1;
- }
-
- check_ir_old_tpx_versions(cr,fplog,ir,top_global);
-
- nstglobalcomm = check_nstglobalcomm(fplog,cr,nstglobalcomm,ir);
- /*bGStatEveryStep = (nstglobalcomm == 1);*/
- bGStatEveryStep = FALSE;
-
- if (!bGStatEveryStep && ir->nstlist == -1 && fplog != NULL)
- {
- fprintf(fplog,
- "To reduce the energy communication with nstlist = -1\n"
- "the neighbor list validity should not be checked at every step,\n"
- "this means that exact integration is not guaranteed.\n"
- "The neighbor list validity is checked after:\n"
- " <n.list life time> - 2*std.dev.(n.list life time) steps.\n"
- "In most cases this will result in exact integration.\n"
- "This reduces the energy communication by a factor of 2 to 3.\n"
- "If you want less energy communication, set nstlist > 3.\n\n");
- }
-
- if (bRerunMD || bFFscan)
- {
- ir->nstxtcout = 0;
- }
- groups = &top_global->groups;
-
- /* Initial values */
- init_md(fplog,cr,ir,oenv,&t,&t0,&state_global->lambda,&lam0,
- nrnb,top_global,&upd,
- nfile,fnm,&outf,&mdebin,
- force_vir,shake_vir,mu_tot,&bSimAnn,&vcm,state_global,Flags);
-
- clear_mat(total_vir);
- clear_mat(pres);
- /* Energy terms and groups */
- snew(enerd,1);
- init_enerdata(top_global->groups.grps[egcENER].nr,ir->n_flambda,enerd);
- if (DOMAINDECOMP(cr))
- {
- f = NULL;
- }
- else
- {
- snew(f,top_global->natoms);
- }
-
- /* Kinetic energy data */
- snew(ekind,1);
- init_ekindata(fplog,top_global,&(ir->opts),ekind);
- /* needed for iteration of constraints */
- snew(ekind_save,1);
- init_ekindata(fplog,top_global,&(ir->opts),ekind_save);
- /* Copy the cos acceleration to the groups struct */
- ekind->cosacc.cos_accel = ir->cos_accel;
-
- gstat = global_stat_init(ir);
- debug_gmx();
-
- /* Check for polarizable models and flexible constraints */
- shellfc = init_shell_flexcon(fplog,
- top_global,n_flexible_constraints(constr),
- (ir->bContinuation ||
- (DOMAINDECOMP(cr) && !MASTER(cr))) ?
- NULL : state_global->x);
-
-/* if (DEFORM(*ir))
- {
-#ifdef GMX_THREADS
- tMPI_Thread_mutex_lock(&deform_init_box_mutex);
-#endif
- set_deform_reference_box(upd,
- deform_init_init_step_tpx,
- deform_init_box_tpx);
-#ifdef GMX_THREADS
- tMPI_Thread_mutex_unlock(&deform_init_box_mutex);
-#endif
- }*/
-
-/* {
- double io = compute_io(ir,top_global->natoms,groups,mdebin->ebin->nener,1);
- if ((io > 2000) && MASTER(cr))
- fprintf(stderr,
- "\nWARNING: This run will generate roughly %.0f Mb of data\n\n",
- io);
- }*/
-
- if (DOMAINDECOMP(cr)) {
- top = dd_init_local_top(top_global);
-
- snew(state,1);
- dd_init_local_state(cr->dd,state_global,state);
-
- if (DDMASTER(cr->dd) && ir->nstfout) {
- snew(f_global,state_global->natoms);
- }
- } else {
- if (PAR(cr)) {
- /* Initialize the particle decomposition and split the topology */
- top = split_system(fplog,top_global,ir,cr);
-
- pd_cg_range(cr,&fr->cg0,&fr->hcg);
- pd_at_range(cr,&a0,&a1);
- } else {
- top = gmx_mtop_generate_local_top(top_global,ir);
-
- a0 = 0;
- a1 = top_global->natoms;
- }
-
- state = partdec_init_local_state(cr,state_global);
- f_global = f;
-
- atoms2md(top_global,ir,0,NULL,a0,a1-a0,mdatoms);
-
- if (vsite) {
- set_vsite_top(vsite,top,mdatoms,cr);
- }
-
- if (ir->ePBC != epbcNONE && !ir->bPeriodicMols) {
- graph = mk_graph(fplog,&(top->idef),0,top_global->natoms,FALSE,FALSE);
- }
-
- if (shellfc) {
- make_local_shells(cr,mdatoms,shellfc);
- }
-
- if (ir->pull && PAR(cr)) {
- dd_make_local_pull_groups(NULL,ir->pull,mdatoms);
- }
- }
-
- if (DOMAINDECOMP(cr))
- {
- /* Distribute the charge groups over the nodes from the master node */
- dd_partition_system(fplog,ir->init_step,cr,TRUE,1,
- state_global,top_global,ir,
- state,&f,mdatoms,top,fr,
- vsite,shellfc,constr,
- nrnb,wcycle,FALSE);
- }
-
- update_mdatoms(mdatoms,state->lambda);
-
- if (MASTER(cr))
- {
- if (opt2bSet("-cpi",nfile,fnm))
- {
- /* Update mdebin with energy history if appending to output files */
- if ( Flags & MD_APPENDFILES )
- {
- restore_energyhistory_from_state(mdebin,&state_global->enerhist);
- }
- else
- {
- /* We might have read an energy history from checkpoint,
- * free the allocated memory and reset the counts.
- */
- done_energyhistory(&state_global->enerhist);
- init_energyhistory(&state_global->enerhist);
- }
- }
- /* Set the initial energy history in state by updating once */
- update_energyhistory(&state_global->enerhist,mdebin);
- }
-
- if ((state->flags & (1<<estLD_RNG)) && (Flags & MD_READ_RNG)) {
- /* Set the random state if we read a checkpoint file */
- set_stochd_state(upd,state);
- }
-
- /* Initialize constraints */
- if (constr) {
- if (!DOMAINDECOMP(cr))
- set_constraints(constr,top,ir,mdatoms,cr);
- }
-
- /* Check whether we have to GCT stuff */
- /* bTCR = ftp2bSet(efGCT,nfile,fnm);
- if (bTCR) {
- if (MASTER(cr)) {
- fprintf(stderr,"Will do General Coupling Theory!\n");
- }
- gnx = top_global->mols.nr;
- snew(grpindex,gnx);
- for(i=0; (i<gnx); i++) {
- grpindex[i] = i;
- }
- }*/
-
-/* if (repl_ex_nst > 0 && MASTER(cr))
- repl_ex = init_replica_exchange(fplog,cr->ms,state_global,ir,
- repl_ex_nst,repl_ex_seed);*/
-
- if (!ir->bContinuation && !bRerunMD)
- {
- if (mdatoms->cFREEZE && (state->flags & (1<<estV)))
- {
- /* Set the velocities of frozen particles to zero */
- for(i=mdatoms->start; i<mdatoms->start+mdatoms->homenr; i++)
- {
- for(m=0; m<DIM; m++)
- {
- if (ir->opts.nFreeze[mdatoms->cFREEZE[i]][m])
- {
- state->v[i][m] = 0;
- }
- }
- }
- }
-
- if (constr)
- {
- /* Constrain the initial coordinates and velocities */
- do_constrain_first(fplog,constr,ir,mdatoms,state,f,
- graph,cr,nrnb,fr,top,shake_vir);
- }
- if (vsite)
- {
- /* Construct the virtual sites for the initial configuration */
- construct_vsites(fplog,vsite,state->x,nrnb,ir->delta_t,NULL,
- top->idef.iparams,top->idef.il,
- fr->ePBC,fr->bMolPBC,graph,cr,state->box);
- }
- }
-
- debug_gmx();
-
- /* I'm assuming we need global communication the first time! MRS */
- cglo_flags = (CGLO_TEMPERATURE | CGLO_GSTAT
- | (bVV ? CGLO_PRESSURE:0)
- | (bVV ? CGLO_CONSTRAINT:0)
- | (bRerunMD ? CGLO_RERUNMD:0)
- | ((Flags & MD_READ_EKIN) ? CGLO_READEKIN:0));
-
- bSumEkinhOld = FALSE;
- 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);
- if (ir->eI == eiVVAK) {
- /* a second call to get the half step temperature initialized as well */
- /* we do the same call as above, but turn the pressure off -- internally, this
- is recognized as a velocity verlet half-step kinetic energy calculation.
- This minimized excess variables, but perhaps loses some logic?*/
-
- 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_PRESSURE);
- }
-
- /* Calculate the initial half step temperature, and save the ekinh_old */
- if (!(Flags & MD_STARTFROMCPT))
- {
- for(i=0; (i<ir->opts.ngtc); i++)
- {
- copy_mat(ekind->tcstat[i].ekinh,ekind->tcstat[i].ekinh_old);
- }
- }
- if (ir->eI != eiVV)
- {
- enerd->term[F_TEMP] *= 2; /* result of averages being done over previous and current step,
- and there is no previous step */
- }
- temp0 = enerd->term[F_TEMP];
-
- /* if using an iterative algorithm, we need to create a working directory for the state. */
- if (bIterations)
- {
- bufstate = init_bufstate(state);
- }
- if (bFFscan)
- {
- snew(xcopy,state->natoms);
- snew(vcopy,state->natoms);
- copy_rvecn(state->x,xcopy,0,state->natoms);
- copy_rvecn(state->v,vcopy,0,state->natoms);
- copy_mat(state->box,boxcopy);
- }
-
- /* need to make an initiation call to get the Trotter variables set, as well as other constants for non-trotter
- temperature control */
- trotter_seq = init_npt_vars(ir,state,&MassQ,bTrotter);
-
- if (MASTER(cr))
- {
- if (constr && !ir->bContinuation && ir->eConstrAlg == econtLINCS)
- {
- fprintf(fplog,
- "RMS relative constraint deviation after constraining: %.2e\n",
- constr_rmsd(constr,FALSE));
- }
- fprintf(fplog,"Initial temperature: %g K\n",enerd->term[F_TEMP]);
- if (bRerunMD)
- {
- fprintf(stderr,"starting md rerun '%s', reading coordinates from"
- " input trajectory '%s'\n\n",
- *(top_global->name),opt2fn("-rerun",nfile,fnm));
- if (bVerbose)
- {
- fprintf(stderr,"Calculated time to finish depends on nsteps from "
- "run input file,\nwhich may not correspond to the time "
- "needed to process input trajectory.\n\n");
- }
- }
- else
- {
- char tbuf[20];
- fprintf(stderr,"starting mdrun '%s'\n",
- *(top_global->name));
- if (ir->nsteps >= 0)
- {
- sprintf(tbuf,"%8.1f",(ir->init_step+ir->nsteps)*ir->delta_t);
- }
- else
- {
- sprintf(tbuf,"%s","infinite");
- }
- if (ir->init_step > 0)
- {
- fprintf(stderr,"%s steps, %s ps (continuing from step %s, %8.1f ps).\n",
- gmx_step_str(ir->init_step+ir->nsteps,sbuf),tbuf,
- gmx_step_str(ir->init_step,sbuf2),
- ir->init_step*ir->delta_t);
- }
- else
- {
- fprintf(stderr,"%s steps, %s ps.\n",
- gmx_step_str(ir->nsteps,sbuf),tbuf);
- }
- }
- fprintf(fplog,"\n");
- }
-
- /* Set and write start time */
- runtime_start(runtime);
- print_date_and_time(fplog,cr->nodeid,"Started mdrun",runtime);
- wallcycle_start(wcycle,ewcRUN);
- if (fplog)
- fprintf(fplog,"\n");
-
- /* safest point to do file checkpointing is here. More general point would be immediately before integrator call */
-/*#ifdef GMX_FAHCORE
- chkpt_ret=fcCheckPointParallel( cr->nodeid,
- NULL,0);
- if ( chkpt_ret == 0 )
- gmx_fatal( 3,__FILE__,__LINE__, "Checkpoint error on step %d\n", 0 );
-#endif*/
-
- debug_gmx();
- /***********************************************************
- *
- * Loop over MD steps
- *
- ************************************************************/
-
- /* if rerunMD then read coordinates and velocities from input trajectory */
- if (bRerunMD)
- {
- if (getenv("GMX_FORCE_UPDATE"))
- {
- bForceUpdate = TRUE;
- }
-
- bNotLastFrame = read_first_frame(oenv,&status,
- opt2fn("-rerun",nfile,fnm),
- &rerun_fr,TRX_NEED_X | TRX_READ_V);
- if (rerun_fr.natoms != top_global->natoms)
- {
- gmx_fatal(FARGS,
- "Number of atoms in trajectory (%d) does not match the "
- "run input file (%d)\n",
- rerun_fr.natoms,top_global->natoms);
- }
- if (ir->ePBC != epbcNONE)
- {
- if (!rerun_fr.bBox)
- {
- gmx_fatal(FARGS,"Rerun trajectory frame step %d time %f does not contain a box, while pbc is used",rerun_fr.step,rerun_fr.time);
- }
- if (max_cutoff2(ir->ePBC,rerun_fr.box) < sqr(fr->rlistlong))
- {
- gmx_fatal(FARGS,"Rerun trajectory frame step %d time %f has too small box dimensions",rerun_fr.step,rerun_fr.time);
- }
-
- /* Set the shift vectors.
- * Necessary here when have a static box different from the tpr box.
- */
- calc_shifts(rerun_fr.box,fr->shift_vec);
- }
- }
-
- /* loop over MD steps or if rerunMD to end of input trajectory */
- bFirstStep = TRUE;
- /* Skip the first Nose-Hoover integration when we get the state from tpx */
- bStateFromTPX = !opt2bSet("-cpi",nfile,fnm);
- bInitStep = bFirstStep && (bStateFromTPX || bVV);
- bStartingFromCpt = (Flags & MD_STARTFROMCPT) && bInitStep;
- bLastStep = FALSE;
- bSumEkinhOld = FALSE;
- bExchanged = FALSE;
-
- init_global_signals(&gs,cr,ir,repl_ex_nst);
-
- step = ir->init_step;
- step_rel = 0;
-
- if (ir->nstlist == -1)
- {
- init_nlistheuristics(&nlh,bGStatEveryStep,step);
- }
-
- bLastStep = (bRerunMD || (ir->nsteps >= 0 && step_rel > ir->nsteps));
- while (!bLastStep || (bRerunMD && bNotLastFrame)) {
-
- wallcycle_start(wcycle,ewcSTEP);
-
- GMX_MPE_LOG(ev_timestep1);
-
- if (bRerunMD) {
- if (rerun_fr.bStep) {
- step = rerun_fr.step;
- step_rel = step - ir->init_step;
- }
- if (rerun_fr.bTime) {
- t = rerun_fr.time;
- }
- else
- {
- t = step;
- }
- }
- else
- {
- bLastStep = (step_rel == ir->nsteps);
- t = t0 + step*ir->delta_t;
- }
-
- if (ir->efep != efepNO)
- {
- if (bRerunMD && rerun_fr.bLambda && (ir->delta_lambda!=0))
- {
- state_global->lambda = rerun_fr.lambda;
- }
- else
- {
- state_global->lambda = lam0 + step*ir->delta_lambda;
- }
- state->lambda = state_global->lambda;
- bDoDHDL = do_per_step(step,ir->nstdhdl);
- }
-
- if (bSimAnn)
- {
- update_annealing_target_temp(&(ir->opts),t);
- }
-
- if (bRerunMD)
- {
- if (!(DOMAINDECOMP(cr) && !MASTER(cr)))
- {
- for(i=0; i<state_global->natoms; i++)
- {
- copy_rvec(rerun_fr.x[i],state_global->x[i]);
- }
- if (rerun_fr.bV)
- {
- for(i=0; i<state_global->natoms; i++)
- {
- copy_rvec(rerun_fr.v[i],state_global->v[i]);
- }
- }
- else
- {
- for(i=0; i<state_global->natoms; i++)
- {
- clear_rvec(state_global->v[i]);
- }
- if (bRerunWarnNoV)
- {
- fprintf(stderr,"\nWARNING: Some frames do not contain velocities.\n"
- " Ekin, temperature and pressure are incorrect,\n"
- " the virial will be incorrect when constraints are present.\n"
- "\n");
- bRerunWarnNoV = FALSE;
- }
- }
- }
- copy_mat(rerun_fr.box,state_global->box);
- copy_mat(state_global->box,state->box);
-
- if (vsite && (Flags & MD_RERUN_VSITE))
- {
- if (DOMAINDECOMP(cr))
- {
- gmx_fatal(FARGS,"Vsite recalculation with -rerun is not implemented for domain decomposition, use particle decomposition");
- }
- if (graph)
- {
- /* Following is necessary because the graph may get out of sync
- * with the coordinates if we only have every N'th coordinate set
- */
- mk_mshift(fplog,graph,fr->ePBC,state->box,state->x);
- shift_self(graph,state->box,state->x);
- }
- construct_vsites(fplog,vsite,state->x,nrnb,ir->delta_t,state->v,
- top->idef.iparams,top->idef.il,
- fr->ePBC,fr->bMolPBC,graph,cr,state->box);
- if (graph)
- {
- unshift_self(graph,state->box,state->x);
- }
- }
- }
-
- /* Stop Center of Mass motion */
- bStopCM = (ir->comm_mode != ecmNO && do_per_step(step,ir->nstcomm));
-
- /* Copy back starting coordinates in case we're doing a forcefield scan */
- if (bFFscan)
- {
- for(ii=0; (ii<state->natoms); ii++)
- {
- copy_rvec(xcopy[ii],state->x[ii]);
- copy_rvec(vcopy[ii],state->v[ii]);
- }
- copy_mat(boxcopy,state->box);
- }
-
- if (bRerunMD)
- {
- /* for rerun MD always do Neighbour Searching */
- bNS = (bFirstStep || ir->nstlist != 0);
- bNStList = bNS;
- }
- else
- {
- /* Determine whether or not to do Neighbour Searching and LR */
- bNStList = (ir->nstlist > 0 && step % ir->nstlist == 0);
-
- bNS = (bFirstStep || bExchanged || bNStList ||
- (ir->nstlist == -1 && nlh.nabnsb > 0));
-
- if (bNS && ir->nstlist == -1)
- {
- set_nlistheuristics(&nlh,bFirstStep || bExchanged,step);
- }
- }
-
- /* < 0 means stop at next step, > 0 means stop at next NS step */
- if ( (gs.set[eglsSTOPCOND] < 0 ) ||
- ( (gs.set[eglsSTOPCOND] > 0 ) && ( bNS || ir->nstlist==0)) )
- {
- bLastStep = TRUE;
- }
-
- /* Determine whether or not to update the Born radii if doing GB */
- bBornRadii=bFirstStep;
- if (ir->implicit_solvent && (step % ir->nstgbradii==0))
- {
- bBornRadii=TRUE;
- }
-
- do_log = do_per_step(step,ir->nstlog) || bFirstStep || bLastStep;
- do_verbose = bVerbose &&
- (step % stepout == 0 || bFirstStep || bLastStep);
-
- if (bNS && !(bFirstStep && ir->bContinuation && !bRerunMD))
- {
- if (bRerunMD)
- {
- bMasterState = TRUE;
- }
- else
- {
- bMasterState = FALSE;
- /* Correct the new box if it is too skewed */
- if (DYNAMIC_BOX(*ir))
- {
- if (correct_box(fplog,step,state->box,graph))
- {
- bMasterState = TRUE;
- }
- }
- if (DOMAINDECOMP(cr) && bMasterState)
- {
- dd_collect_state(cr->dd,state,state_global);
- }
- }
-
- if (DOMAINDECOMP(cr))
- {
- /* Repartition the domain decomposition */
- wallcycle_start(wcycle,ewcDOMDEC);
- dd_partition_system(fplog,step,cr,
- bMasterState,nstglobalcomm,
- state_global,top_global,ir,
- state,&f,mdatoms,top,fr,
- vsite,shellfc,constr,
- nrnb,wcycle,do_verbose);
- wallcycle_stop(wcycle,ewcDOMDEC);
- /* If using an iterative integrator, reallocate space to match the decomposition */
- }
- }
-
- if (MASTER(cr) && do_log && !bFFscan)
- {
- print_ebin_header(fplog,step,t,state->lambda);
- }
-
- if (ir->efep != efepNO)
- {
- update_mdatoms(mdatoms,state->lambda);
- }
-
- if (bRerunMD && rerun_fr.bV)
- {
-
- /* We need the kinetic energy at minus the half step for determining
- * the full step kinetic energy and possibly for T-coupling.*/
- /* This may not be quite working correctly yet . . . . */
- compute_globals(fplog,gstat,cr,ir,fr,ekind,state,state_global,mdatoms,nrnb,vcm,
- wcycle,enerd,NULL,NULL,NULL,NULL,mu_tot,
- constr,NULL,FALSE,state->box,
- top_global,&pcurr,top_global->natoms,&bSumEkinhOld,
- CGLO_RERUNMD | CGLO_GSTAT | CGLO_TEMPERATURE);
- }
- clear_mat(force_vir);
-
- /* Ionize the atoms if necessary */
-/* if (bIonize)
- {
- ionize(fplog,oenv,mdatoms,top_global,t,ir,state->x,state->v,
- mdatoms->start,mdatoms->start+mdatoms->homenr,state->box,cr);
- }*/
-
- /* Update force field in ffscan program */
-/* if (bFFscan)
- {
- if (update_forcefield(fplog,
- nfile,fnm,fr,
- mdatoms->nr,state->x,state->box)) {
- if (gmx_parallel_env_initialized())
- {
- gmx_finalize();
- }
- exit(0);
- }
- }*/
-
- GMX_MPE_LOG(ev_timestep2);
-
- /* We write a checkpoint at this MD step when:
- * either at an NS step when we signalled through gs,
- * or at the last step (but not when we do not want confout),
- * but never at the first step or with rerun.
- */
-/* bCPT = (((gs.set[eglsCHKPT] && bNS) ||
- (bLastStep && (Flags & MD_CONFOUT))) &&
- step > ir->init_step && !bRerunMD);
- if (bCPT)
- {
- gs.set[eglsCHKPT] = 0;
- }*/
-
- /* Determine the energy and pressure:
- * at nstcalcenergy steps and at energy output steps (set below).
- */
- bNstEner = (bGStatEveryStep || do_per_step(step,ir->nstcalcenergy));
- bCalcEnerPres = bNstEner;
-
- /* Do we need global communication ? */
- bGStat = (bCalcEnerPres || bStopCM ||
- (ir->nstlist == -1 && !bRerunMD && step >= nlh.step_nscheck));
-
- do_ene = (do_per_step(step,ir->nstenergy) || bLastStep);
-
- if (do_ene || do_log)
- {
- bCalcEnerPres = TRUE;
- bGStat = TRUE;
- }
-
- /* these CGLO_ options remain the same throughout the iteration */
- cglo_flags = ((bRerunMD ? CGLO_RERUNMD : 0) |
- (bStopCM ? CGLO_STOPCM : 0) |
- (bGStat ? CGLO_GSTAT : 0)
- );
-
- force_flags = (GMX_FORCE_STATECHANGED |
- ((DYNAMIC_BOX(*ir) || bRerunMD) ? GMX_FORCE_DYNAMICBOX : 0) |
- GMX_FORCE_ALLFORCES |
- (bNStList ? GMX_FORCE_DOLR : 0) |
- GMX_FORCE_SEPLRF |
- (bCalcEnerPres ? GMX_FORCE_VIRIAL : 0) |
- (bDoDHDL ? GMX_FORCE_DHDL : 0)
- );
-
- if (shellfc)
- {
- /* Now is the time to relax the shells */
- count=relax_shell_flexcon(fplog,cr,bVerbose,bFFscan ? step+1 : step,
- ir,bNS,force_flags,
- bStopCM,top,top_global,
- constr,enerd,fcd,
- state,f,force_vir,mdatoms,
- nrnb,wcycle,graph,groups,
- shellfc,fr,bBornRadii,t,mu_tot,
- state->natoms,&bConverged,vsite,
- outf->fp_field);
- tcount+=count;
-
- if (bConverged)
- {
- nconverged++;
- }
- }
- else
- {
- /* The coordinates (x) are shifted (to get whole molecules)
- * in do_force.
- * This is parallellized as well, and does communication too.
- * Check comments in sim_util.c
- */
-
- do_force(fplog,cr,ir,step,nrnb,wcycle,top,top_global,groups,
- state->box,state->x,&state->hist,
- f,force_vir,mdatoms,enerd,fcd,
- state->lambda,graph,
- fr,vsite,mu_tot,t,outf->fp_field,ed,bBornRadii,
- (bNS ? GMX_FORCE_NS : 0) | force_flags);
- }
-
- GMX_BARRIER(cr->mpi_comm_mygroup);
-
- /* if (bTCR)
- {
- mu_aver = calc_mu_aver(cr,state->x,mdatoms->chargeA,
- mu_tot,&top_global->mols,mdatoms,gnx,grpindex);
- }
-
- if (bTCR && bFirstStep)
- {
- tcr=init_coupling(fplog,nfile,fnm,cr,fr,mdatoms,&(top->idef));
- fprintf(fplog,"Done init_coupling\n");
- fflush(fplog);
- }*/
-
- /* ############### START FIRST UPDATE HALF-STEP ############### */
-
- if (bVV && !bStartingFromCpt && !bRerunMD)
- {
- if (ir->eI == eiVV)
- {
- if (bInitStep)
- {
- /* if using velocity verlet with full time step Ekin,
- * take the first half step only to compute the
- * virial for the first step. From there,
- * revert back to the initial coordinates
- * so that the input is actually the initial step.
- */
- copy_rvecn(state->v,cbuf,0,state->natoms); /* should make this better for parallelizing? */
- }
-
- /* this is for NHC in the Ekin(t+dt/2) version of vv */
- if (!bInitStep)
- {
- trotter_update(ir,step,ekind,enerd,state,total_vir,mdatoms,&MassQ,trotter_seq,ettTSEQ2);
- }
-
- if (ir->eI == eiVVAK)
- {
- update_tcouple(fplog,step,ir,state,ekind,wcycle,upd,&MassQ,mdatoms);
- }
-
- update_coords(fplog,step,ir,mdatoms,state,
- f,fr->bTwinRange && bNStList,fr->f_twin,fcd,
- ekind,M,wcycle,upd,bInitStep,etrtVELOCITY1,
- cr,nrnb,constr,&top->idef);
-
- if (bIterations)
- {
- gmx_iterate_init(&iterate,bIterations && !bInitStep);
- }
- /* for iterations, we save these vectors, as we will be self-consistently iterating
- the calculations */
- /*#### UPDATE EXTENDED VARIABLES IN TROTTER FORMULATION */
-
- /* save the state */
- if (bIterations && iterate.bIterate) {
- copy_coupling_state(state,bufstate,ekind,ekind_save,&(ir->opts));
- }
- }
-
- bFirstIterate = TRUE;
- while (bFirstIterate || (bIterations && iterate.bIterate))
- {
- if (bIterations && iterate.bIterate)
- {
- copy_coupling_state(bufstate,state,ekind_save,ekind,&(ir->opts));
- if (bFirstIterate && bTrotter)
- {
- /* The first time through, we need a decent first estimate
- of veta(t+dt) to compute the constraints. Do
- this by computing the box volume part of the
- trotter integration at this time. Nothing else
- should be changed by this routine here. If
- !(first time), we start with the previous value
- of veta. */
-
- veta_save = state->veta;
- trotter_update(ir,step,ekind,enerd,state,total_vir,mdatoms,&MassQ,trotter_seq,ettTSEQ0);
- vetanew = state->veta;
- state->veta = veta_save;
- }
- }
-
- bOK = TRUE;
- if ( !bRerunMD || rerun_fr.bV || bForceUpdate) { /* Why is rerun_fr.bV here? Unclear. */
- dvdl = 0;
-
- update_constraints(fplog,step,&dvdl,ir,ekind,mdatoms,state,graph,f,
- &top->idef,shake_vir,NULL,
- cr,nrnb,wcycle,upd,constr,
- bInitStep,TRUE,bCalcEnerPres,vetanew);
-
- if (!bOK && !bFFscan)
- {
- gmx_fatal(FARGS,"Constraint error: Shake, Lincs or Settle could not solve the constrains");
- }
-
- }
- else if (graph)
- { /* Need to unshift here if a do_force has been
- called in the previous step */
- unshift_self(graph,state->box,state->x);
- }
-
-
- if (bVV) {
- /* if VV, compute the pressure and constraints */
- /* if VV2, the pressure and constraints only if using pressure control.*/
- bPres = (ir->eI==eiVV || IR_NPT_TROTTER(ir));
- bTemp = ((ir->eI==eiVV &&(!bInitStep)) || (ir->eI==eiVVAK && IR_NPT_TROTTER(ir)));
- 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.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.
- 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 */
-
- /* temperature scaling and pressure scaling to produce the extended variables at t+dt */
- if (bVV && !bInitStep)
- {
- trotter_update(ir,step,ekind,enerd,state,total_vir,mdatoms,&MassQ, trotter_seq,ettTSEQ2);
- }
-
- if (bIterations &&
- done_iterating(cr,fplog,step,&iterate,bFirstIterate,
- state->veta,&vetanew))
- {
- break;
- }
- bFirstIterate = FALSE;
- }
-
- if (bTrotter && !bInitStep) {
- copy_mat(shake_vir,state->svir_prev);
- copy_mat(force_vir,state->fvir_prev);
- if (IR_NVT_TROTTER(ir) && ir->eI==eiVV) {
- /* update temperature and kinetic energy now that step is over - this is the v(t+dt) point */
- enerd->term[F_TEMP] = sum_ekin(&(ir->opts),ekind,NULL,(ir->eI==eiVV),FALSE,FALSE);
- enerd->term[F_EKIN] = trace(ekind->ekin);
- }
- }
- /* if it's the initial step, we performed this first step just to get the constraint virial */
- if (bInitStep && ir->eI==eiVV) {
- copy_rvecn(cbuf,state->v,0,state->natoms);
- }
-
- if (fr->bSepDVDL && fplog && do_log)
- {
- fprintf(fplog,sepdvdlformat,"Constraint",0.0,dvdl);
- }
- enerd->term[F_DHDL_CON] += dvdl;
-
- GMX_MPE_LOG(ev_timestep1);
-
- }
-
- /* MRS -- now done iterating -- compute the conserved quantity */
- if (bVV) {
- last_conserved = 0;
- if (IR_NVT_TROTTER(ir) || IR_NPT_TROTTER(ir))
- {
- last_conserved =
- NPT_energy(ir,state,&MassQ);
- if ((ir->eDispCorr != edispcEnerPres) && (ir->eDispCorr != edispcAllEnerPres))
- {
- last_conserved -= enerd->term[F_DISPCORR];
- }
- }
- if (ir->eI==eiVV) {
- last_ekin = enerd->term[F_EKIN]; /* does this get preserved through checkpointing? */
- }
- }
-
- /* ######## END FIRST UPDATE STEP ############## */
- /* ######## If doing VV, we now have v(dt) ###### */
-
- /* ################## START TRAJECTORY OUTPUT ################# */
-
- /* Now we have the energies and forces corresponding to the
- * coordinates at time t. We must output all of this before
- * 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)) { mdof_flags |= MDOF_X; }
- if (do_per_step(step,ir->nstvout)) { mdof_flags |= MDOF_V; }
- if (do_per_step(step,ir->nstfout)) { mdof_flags |= MDOF_F; }
- if (do_per_step(step,ir->nstxtcout)) { mdof_flags |= MDOF_XTC; }
-/* if (bCPT) { mdof_flags |= MDOF_CPT; };*/
-
-#ifdef GMX_FAHCORE
- if (MASTER(cr))
- fcReportProgress( ir->nsteps, step );
-
- if (bLastStep)
- {
- /* Enforce writing positions and velocities at end of run */
- mdof_flags |= (MDOF_X | MDOF_V);
- }
- /* sync bCPT and fc record-keeping */
-/* if (bCPT && MASTER(cr))
- fcRequestCheckPoint();*/
-#endif
-
- if (mdof_flags != 0)
- {
- wallcycle_start(wcycle,ewcTRAJ);
-/* if (bCPT)
- {
- if (state->flags & (1<<estLD_RNG))
- {
- get_stochd_state(upd,state);
- }
- if (MASTER(cr))
- {
- if (bSumEkinhOld)
- {
- state_global->ekinstate.bUpToDate = FALSE;
- }
- else
- {
- update_ekinstate(&state_global->ekinstate,ekind);
- state_global->ekinstate.bUpToDate = TRUE;
- }
- update_energyhistory(&state_global->enerhist,mdebin);
- }
- }*/
- write_traj(fplog,cr,outf,mdof_flags,top_global,
- step,t,state,state_global,f,f_global,&n_xtc,&x_xtc);
-/* if (bCPT)
- {
- nchkpt++;
- bCPT = FALSE;
- }*/
- debug_gmx();
- if (bLastStep && step_rel == ir->nsteps &&
- (Flags & MD_CONFOUT) && MASTER(cr) &&
- !bRerunMD && !bFFscan)
- {
- /* x and v have been collected in write_traj,
- * because a checkpoint file will always be written
- * at the last step.
- */
- fprintf(stderr,"\nWriting final coordinates.\n");
- if (ir->ePBC != epbcNONE && !ir->bPeriodicMols &&
- DOMAINDECOMP(cr))
- {
- /* Make molecules whole only for confout writing */
- do_pbc_mtop(fplog,ir->ePBC,state->box,top_global,state_global->x);
- }
-/* write_sto_conf_mtop(ftp2fn(efSTO,nfile,fnm),
- *top_global->name,top_global,
- state_global->x,state_global->v,
- ir->ePBC,state->box);*/
- debug_gmx();
- }
- wallcycle_stop(wcycle,ewcTRAJ);
- }
- GMX_MPE_LOG(ev_output_finish);
-
- /* kludge -- virial is lost with restart for NPT control. Must restart */
- if (bStartingFromCpt && bVV)
- {
- copy_mat(state->svir_prev,shake_vir);
- copy_mat(state->fvir_prev,force_vir);
- }
- /* ################## END TRAJECTORY OUTPUT ################ */
-
- /* Determine the pressure:
- * always when we want exact averages in the energy file,
- * at ns steps when we have pressure coupling,
- * otherwise only at energy output steps (set below).
- */
-
- bNstEner = (bGStatEveryStep || do_per_step(step,ir->nstcalcenergy));
- bCalcEnerPres = bNstEner;
-
- /* Do we need global communication ? */
- bGStat = (bGStatEveryStep || bStopCM || bNS ||
- (ir->nstlist == -1 && !bRerunMD && step >= nlh.step_nscheck));
-
- do_ene = (do_per_step(step,ir->nstenergy) || bLastStep);
-
- if (do_ene || do_log)
- {
- bCalcEnerPres = TRUE;
- bGStat = TRUE;
- }
-
- /* Determine the wallclock run time up till now */
- run_time = gmx_gettime() - (double)runtime->real;
-
- /* Check whether everything is still allright */
- if (((int)gmx_get_stop_condition() > handled_stop_condition)
-#ifdef GMX_THREADS
- && MASTER(cr)
-#endif
- )
- {
- /* this is just make gs.sig compatible with the hack
- of sending signals around by MPI_Reduce with together with
- other floats */
- if ( gmx_get_stop_condition() == gmx_stop_cond_next_ns )
- gs.sig[eglsSTOPCOND]=1;
- if ( gmx_get_stop_condition() == gmx_stop_cond_next )
- gs.sig[eglsSTOPCOND]=-1;
- /* < 0 means stop at next step, > 0 means stop at next NS step */
- if (fplog)
- {
- fprintf(fplog,
- "\n\nReceived the %s signal, stopping at the next %sstep\n\n",
- gmx_get_signal_name(),
- gs.sig[eglsSTOPCOND]==1 ? "NS " : "");
- fflush(fplog);
- }
- fprintf(stderr,
- "\n\nReceived the %s signal, stopping at the next %sstep\n\n",
- gmx_get_signal_name(),
- gs.sig[eglsSTOPCOND]==1 ? "NS " : "");
- fflush(stderr);
- handled_stop_condition=(int)gmx_get_stop_condition();
- }
- else if (MASTER(cr) && (bNS || ir->nstlist <= 0) &&
- (max_hours > 0 && run_time > max_hours*60.0*60.0*0.99) &&
- gs.sig[eglsSTOPCOND] == 0 && gs.set[eglsSTOPCOND] == 0)
- {
- /* Signal to terminate the run */
- gs.sig[eglsSTOPCOND] = 1;
- if (fplog)
- {
- fprintf(fplog,"\nStep %s: Run time exceeded %.3f hours, will terminate the run\n",gmx_step_str(step,sbuf),max_hours*0.99);
- }
- fprintf(stderr, "\nStep %s: Run time exceeded %.3f hours, will terminate the run\n",gmx_step_str(step,sbuf),max_hours*0.99);
- }
-
- if (bResetCountersHalfMaxH && MASTER(cr) &&
- run_time > max_hours*60.0*60.0*0.495)
- {
- gs.sig[eglsRESETCOUNTERS] = 1;
- }
-
- if (ir->nstlist == -1 && !bRerunMD)
- {
- /* When bGStatEveryStep=FALSE, global_stat is only called
- * when we check the atom displacements, not at NS steps.
- * This means that also the bonded interaction count check is not
- * performed immediately after NS. Therefore a few MD steps could
- * be performed with missing interactions.
- * But wrong energies are never written to file,
- * since energies are only written after global_stat
- * has been called.
- */
- if (step >= nlh.step_nscheck)
- {
- nlh.nabnsb = natoms_beyond_ns_buffer(ir,fr,&top->cgs,
- nlh.scale_tot,state->x);
- }
- else
- {
- /* This is not necessarily true,
- * but step_nscheck is determined quite conservatively.
- */
- nlh.nabnsb = 0;
- }
- }
-
- /* In parallel we only have to check for checkpointing in steps
- * where we do global communication,
- * otherwise the other nodes don't know.
- */
- if (MASTER(cr) && ((bGStat || !PAR(cr)) &&
- cpt_period >= 0 &&
- (cpt_period == 0 ||
- run_time >= nchkpt*cpt_period*60.0)) &&
- gs.set[eglsCHKPT] == 0)
- {
- gs.sig[eglsCHKPT] = 1;
- }
-
- if (bIterations)
- {
- gmx_iterate_init(&iterate,bIterations);
- }
-
- /* for iterations, we save these vectors, as we will be redoing the calculations */
- if (bIterations && iterate.bIterate)
- {
- copy_coupling_state(state,bufstate,ekind,ekind_save,&(ir->opts));
- }
- bFirstIterate = TRUE;
- while (bFirstIterate || (bIterations && iterate.bIterate))
- {
- /* We now restore these vectors to redo the calculation with improved extended variables */
- if (bIterations)
- {
- copy_coupling_state(bufstate,state,ekind_save,ekind,&(ir->opts));
- }
-
- /* We make the decision to break or not -after- the calculation of Ekin and Pressure,
- so scroll down for that logic */
-
- /* ######### START SECOND UPDATE STEP ################# */
- GMX_MPE_LOG(ev_update_start);
- bOK = TRUE;
- if (!bRerunMD || rerun_fr.bV || bForceUpdate)
- {
- wallcycle_start(wcycle,ewcUPDATE);
- dvdl = 0;
- /* Box is changed in update() when we do pressure coupling,
- * but we should still use the old box for energy corrections and when
- * writing it to the energy file, so it matches the trajectory files for
- * the same timestep above. Make a copy in a separate array.
- */
- copy_mat(state->box,lastbox);
- /* UPDATE PRESSURE VARIABLES IN TROTTER FORMULATION WITH CONSTRAINTS */
- if (bTrotter)
- {
- if (bIterations && iterate.bIterate)
- {
- if (bFirstIterate)
- {
- scalevir = 1;
- }
- else
- {
- /* we use a new value of scalevir to converge the iterations faster */
- scalevir = tracevir/trace(shake_vir);
- }
- msmul(shake_vir,scalevir,shake_vir);
- m_add(force_vir,shake_vir,total_vir);
- clear_mat(shake_vir);
- }
- trotter_update(ir,step,ekind,enerd,state,total_vir,mdatoms,&MassQ, trotter_seq,ettTSEQ3);
- }
- /* We can only do Berendsen coupling after we have summed
- * the kinetic energy or virial. Since the happens
- * in global_state after update, we should only do it at
- * step % nstlist = 1 with bGStatEveryStep=FALSE.
- */
-
- if (ir->eI != eiVVAK)
- {
- update_tcouple(fplog,step,ir,state,ekind,wcycle,upd,&MassQ,mdatoms);
- }
- update_pcouple(fplog,step,ir,state,pcoupl_mu,M,wcycle,
- upd,bInitStep);
-
- if (bVV)
- {
- /* velocity half-step update */
- update_coords(fplog,step,ir,mdatoms,state,f,fr->bTwinRange && bNStList,fr->f_twin,fcd,
- ekind,M,wcycle,upd,FALSE,etrtVELOCITY2,cr,nrnb,constr,&top->idef);
- }
-
- /* Above, initialize just copies ekinh into ekin,
- * it doesn't copy position (for VV),
- * and entire integrator for MD.
- */
-
- if (ir->eI==eiVVAK)
- {
- copy_rvecn(state->x,cbuf,0,state->natoms);
- }
-
- update_coords(fplog,step,ir,mdatoms,state,f,fr->bTwinRange && bNStList,fr->f_twin,fcd,
- ekind,M,wcycle,upd,bInitStep,etrtPOSITION,cr,nrnb,constr,&top->idef);
- wallcycle_stop(wcycle,ewcUPDATE);
-
- update_constraints(fplog,step,&dvdl,ir,ekind,mdatoms,state,graph,f,
- &top->idef,shake_vir,force_vir,
- cr,nrnb,wcycle,upd,constr,
- bInitStep,FALSE,bCalcEnerPres,state->veta);
-
- if (ir->eI==eiVVAK)
- {
- /* erase F_EKIN and F_TEMP here? */
- /* just compute the kinetic energy at the half step to perform a trotter step */
- 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,lastbox,
- top_global,&pcurr,top_global->natoms,&bSumEkinhOld,
- cglo_flags | CGLO_TEMPERATURE | CGLO_CONSTRAINT
- );
- wallcycle_start(wcycle,ewcUPDATE);
- trotter_update(ir,step,ekind,enerd,state,total_vir,mdatoms,&MassQ, trotter_seq,ettTSEQ4);
- /* now we know the scaling, we can compute the positions again again */
- copy_rvecn(cbuf,state->x,0,state->natoms);
-
- update_coords(fplog,step,ir,mdatoms,state,f,fr->bTwinRange && bNStList,fr->f_twin,fcd,
- ekind,M,wcycle,upd,bInitStep,etrtPOSITION,cr,nrnb,constr,&top->idef);
- wallcycle_stop(wcycle,ewcUPDATE);
-
- /* do we need an extra constraint here? just need to copy out of state->v to upd->xp? */
- /* are the small terms in the shake_vir here due
- * to numerical errors, or are they important
- * physically? I'm thinking they are just errors, but not completely sure.
- * For now, will call without actually constraining, constr=NULL*/
- update_constraints(fplog,step,&dvdl,ir,ekind,mdatoms,state,graph,f,
- &top->idef,tmp_vir,force_vir,
- cr,nrnb,wcycle,upd,NULL,
- bInitStep,FALSE,bCalcEnerPres,state->veta);
- }
- if (!bOK && !bFFscan)
- {
- gmx_fatal(FARGS,"Constraint error: Shake, Lincs or Settle could not solve the constrains");
- }
-
- if (fr->bSepDVDL && fplog && do_log)
- {
- fprintf(fplog,sepdvdlformat,"Constraint",0.0,dvdl);
- }
- enerd->term[F_DHDL_CON] += dvdl;
- }
- else if (graph)
- {
- /* Need to unshift here */
- unshift_self(graph,state->box,state->x);
- }
-
- GMX_BARRIER(cr->mpi_comm_mygroup);
- GMX_MPE_LOG(ev_update_finish);
-
- if (vsite != NULL)
- {
- wallcycle_start(wcycle,ewcVSITECONSTR);
- if (graph != NULL)
- {
- shift_self(graph,state->box,state->x);
- }
- construct_vsites(fplog,vsite,state->x,nrnb,ir->delta_t,state->v,
- top->idef.iparams,top->idef.il,
- fr->ePBC,fr->bMolPBC,graph,cr,state->box);
-
- if (graph != NULL)
- {
- unshift_self(graph,state->box,state->x);
- }
- wallcycle_stop(wcycle,ewcVSITECONSTR);
- }
-
- /* ############## IF NOT VV, Calculate globals HERE, also iterate constraints ############ */
- if (ir->nstlist == -1 && bFirstIterate)
- {
- gs.sig[eglsNABNSB] = nlh.nabnsb;
- }
- 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,
- bFirstIterate ? &gs : NULL,(step % gs.nstms == 0),
- lastbox,
- top_global,&pcurr,top_global->natoms,&bSumEkinhOld,
- cglo_flags
- | (!EI_VV(ir->eI) ? CGLO_ENERGY : 0)
- | (!EI_VV(ir->eI) ? CGLO_TEMPERATURE : 0)
- | (!EI_VV(ir->eI) || bRerunMD ? CGLO_PRESSURE : 0)
- | (bIterations && iterate.bIterate ? CGLO_ITERATE : 0)
- | (bFirstIterate ? CGLO_FIRSTITERATE : 0)
- | CGLO_CONSTRAINT
- );
- if (ir->nstlist == -1 && bFirstIterate)
- {
- nlh.nabnsb = gs.set[eglsNABNSB];
- gs.set[eglsNABNSB] = 0;
- }
- /* bIterate is set to keep it from eliminating the old ekin kinetic energy terms */
- /* ############# END CALC EKIN AND PRESSURE ################# */
-
- /* Note: this is OK, but there are some numerical precision issues with using the convergence of
- the virial that should probably be addressed eventually. state->veta has better properies,
- 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 &&
- done_iterating(cr,fplog,step,&iterate,bFirstIterate,
- trace(shake_vir),&tracevir))
- {
- break;
- }
- bFirstIterate = FALSE;
- }
-
- update_box(fplog,step,ir,mdatoms,state,graph,f,
- ir->nstlist==-1 ? &nlh.scale_tot : NULL,pcoupl_mu,nrnb,wcycle,upd,bInitStep,FALSE);
-
- /* ################# END UPDATE STEP 2 ################# */
- /* #### We now have r(t+dt) and v(t+dt/2) ############# */
-
- /* The coordinates (x) were unshifted in update */
-/* if (bFFscan && (shellfc==NULL || bConverged))
- {
- if (print_forcefield(fplog,enerd->term,mdatoms->homenr,
- f,NULL,xcopy,
- &(top_global->mols),mdatoms->massT,pres))
- {
- if (gmx_parallel_env_initialized())
- {
- gmx_finalize();
- }
- fprintf(stderr,"\n");
- exit(0);
- }
- }*/
- if (!bGStat)
- {
- /* We will not sum ekinh_old,
- * so signal that we still have to do it.
- */
- bSumEkinhOld = TRUE;
- }
-
-/* if (bTCR)
- {*/
- /* Only do GCT when the relaxation of shells (minimization) has converged,
- * otherwise we might be coupling to bogus energies.
- * In parallel we must always do this, because the other sims might
- * update the FF.
- */
-
- /* Since this is called with the new coordinates state->x, I assume
- * we want the new box state->box too. / EL 20040121
- */
-/* do_coupling(fplog,oenv,nfile,fnm,tcr,t,step,enerd->term,fr,
- ir,MASTER(cr),
- mdatoms,&(top->idef),mu_aver,
- top_global->mols.nr,cr,
- state->box,total_vir,pres,
- mu_tot,state->x,f,bConverged);
- debug_gmx();
- }*/
-
- /* ######### BEGIN PREPARING EDR OUTPUT ########### */
-
- sum_dhdl(enerd,state->lambda,ir);
- /* use the directly determined last velocity, not actually the averaged half steps */
- if (bTrotter && ir->eI==eiVV)
- {
- enerd->term[F_EKIN] = last_ekin;
- }
- enerd->term[F_ETOT] = enerd->term[F_EPOT] + enerd->term[F_EKIN];
-
- switch (ir->etc)
- {
- case etcNO:
- break;
- case etcBERENDSEN:
- break;
- case etcNOSEHOOVER:
- if (IR_NVT_TROTTER(ir)) {
- enerd->term[F_ECONSERVED] = enerd->term[F_ETOT] + last_conserved;
- } else {
- enerd->term[F_ECONSERVED] = enerd->term[F_ETOT] +
- NPT_energy(ir,state,&MassQ);
- }
- break;
- case etcVRESCALE:
- enerd->term[F_ECONSERVED] =
- enerd->term[F_ETOT] + vrescale_energy(&(ir->opts),
- state->therm_integral);
- break;
- default:
- break;
- }
-
- /* Check for excessively large energies */
-/* if (bIonize)
- {
-#ifdef GMX_DOUBLE
- real etot_max = 1e200;
-#else
- real etot_max = 1e30;
-#endif
- if (fabs(enerd->term[F_ETOT]) > etot_max)
- {
- fprintf(stderr,"Energy too large (%g), giving up\n",
- enerd->term[F_ETOT]);
- }
- }*/
- /* ######### END PREPARING EDR OUTPUT ########### */
-
- /* Time for performance */
- if (((step % stepout) == 0) || bLastStep)
- {
- runtime_upd_proc(runtime);
- }
-
- /* Output stuff */
- if (MASTER(cr))
- {
- gmx_bool do_dr,do_or;
-
- if (!(bStartingFromCpt && (EI_VV(ir->eI))))
- {
- if (bNstEner)
- {
- upd_mdebin(mdebin,bDoDHDL,TRUE,
- t,mdatoms->tmass,enerd,state,lastbox,
- shake_vir,force_vir,total_vir,pres,
- ekind,mu_tot,constr);
- }
- else
- {
- upd_mdebin_step(mdebin);
- }
-
- do_dr = do_per_step(step,ir->nstdisreout);
- do_or = do_per_step(step,ir->nstorireout);
-
- print_ebin(outf->fp_ene,do_ene,do_dr,do_or,do_log?fplog:NULL,
- step,t,
- eprNORMAL,bCompact,mdebin,fcd,groups,&(ir->opts));
- }
- if (ir->ePull != epullNO)
- {
- pull_print_output(ir->pull,step,t);
- }
-
- if (do_per_step(step,ir->nstlog))
- {
- if(fflush(fplog) != 0)
- {
- gmx_fatal(FARGS,"Cannot flush logfile - maybe you are out of quota?");
- }
- }
- }
-
-
- /* Remaining runtime */
- if (MULTIMASTER(cr) && (do_verbose || gmx_got_usr_signal() ))
- {
- if (shellfc)
- {
- fprintf(stderr,"\n");
- }
- print_time(stderr,runtime,step,ir,cr);
- }
-
- /* Set new positions for the group to embed */
- if(!bLastStep){
- if(step_rel<=it_xy)
- {
- fac[0]+=xy_step;
- fac[1]+=xy_step;
- } else if (step_rel<=(it_xy+it_z))
- {
- fac[2]+=z_step;
- }
- resize(ins_at,r_ins,state_global->x,pos_ins,fac);
- }
-
- /* Replica exchange */
-/* bExchanged = FALSE;
- if ((repl_ex_nst > 0) && (step > 0) && !bLastStep &&
- do_per_step(step,repl_ex_nst))
- {
- bExchanged = replica_exchange(fplog,cr,repl_ex,
- state_global,enerd->term,
- state,step,t);
- }
- if (bExchanged && PAR(cr))
- {
- if (DOMAINDECOMP(cr))
- {
- dd_partition_system(fplog,step,cr,TRUE,1,
- state_global,top_global,ir,
- state,&f,mdatoms,top,fr,
- vsite,shellfc,constr,
- nrnb,wcycle,FALSE);
- }
- else
- {
- bcast_state(cr,state,FALSE);
- }
- }*/
-
- bFirstStep = FALSE;
- bInitStep = FALSE;
- bStartingFromCpt = FALSE;
-
- /* ####### SET VARIABLES FOR NEXT ITERATION IF THEY STILL NEED IT ###### */
- /* Complicated conditional when bGStatEveryStep=FALSE.
- * We can not just use bGStat, since then the simulation results
- * would depend on nstenergy and nstlog or step_nscheck.
- */
- if (((state->flags & (1<<estPRES_PREV)) ||
- (state->flags & (1<<estSVIR_PREV)) ||
- (state->flags & (1<<estFVIR_PREV))) &&
- (bGStatEveryStep ||
- (ir->nstlist > 0 && step % ir->nstlist == 0) ||
- (ir->nstlist < 0 && nlh.nabnsb > 0) ||
- (ir->nstlist == 0 && bGStat)))
- {
- /* Store the pressure in t_state for pressure coupling
- * at the next MD step.
- */
- if (state->flags & (1<<estPRES_PREV))
- {
- copy_mat(pres,state->pres_prev);
- }
- }
-
- /* ####### END SET VARIABLES FOR NEXT ITERATION ###### */
-
- if (bRerunMD)
- {
- /* read next frame from input trajectory */
- bNotLastFrame = read_next_frame(oenv,status,&rerun_fr);
- }
-
- if (!bRerunMD || !rerun_fr.bStep)
- {
- /* increase the MD step number */
- step++;
- step_rel++;
- }
-
- cycles = wallcycle_stop(wcycle,ewcSTEP);
- if (DOMAINDECOMP(cr) && wcycle)
- {
- dd_cycles_add(cr->dd,cycles,ddCyclStep);
- }
-
- if (step_rel == wcycle_get_reset_counters(wcycle) ||
- gs.set[eglsRESETCOUNTERS] != 0)
- {
- /* Reset all the counters related to performance over the run */
- reset_all_counters(fplog,cr,step,&step_rel,ir,wcycle,nrnb,runtime);
- wcycle_set_reset_counters(wcycle,-1);
- bResetCountersHalfMaxH = FALSE;
- gs.set[eglsRESETCOUNTERS] = 0;
- }
- }
- /* End of main MD loop */
- debug_gmx();
- write_sto_conf_mtop(ftp2fn(efSTO,nfile,fnm),
- *top_global->name,top_global,
- state_global->x,state_global->v,
- ir->ePBC,state->box);
-
- /* Stop the time */
- runtime_end(runtime);
-
- if (bRerunMD)
- {
- close_trj(status);
- }
-
- if (!(cr->duty & DUTY_PME))
- {
- /* Tell the PME only node to finish */
- gmx_pme_finish(cr);
- }
-
- if (MASTER(cr))
- {
- if (ir->nstcalcenergy > 0 && !bRerunMD)
- {
- print_ebin(outf->fp_ene,FALSE,FALSE,FALSE,fplog,step,t,
- eprAVER,FALSE,mdebin,fcd,groups,&(ir->opts));
- }
- }
-
- done_mdoutf(outf);
-
- debug_gmx();
-
- if (ir->nstlist == -1 && nlh.nns > 0 && fplog)
- {
- fprintf(fplog,"Average neighborlist lifetime: %.1f steps, std.dev.: %.1f steps\n",nlh.s1/nlh.nns,sqrt(nlh.s2/nlh.nns - sqr(nlh.s1/nlh.nns)));
- fprintf(fplog,"Average number of atoms that crossed the half buffer length: %.1f\n\n",nlh.ab/nlh.nns);
- }
-
- if (shellfc && fplog)
- {
- fprintf(fplog,"Fraction of iterations that converged: %.2f %%\n",
- (nconverged*100.0)/step_rel);
- fprintf(fplog,"Average number of force evaluations per MD step: %.2f\n\n",
- tcount/step_rel);
- }
-
-/* if (repl_ex_nst > 0 && MASTER(cr))
- {
- print_replica_exchange_statistics(fplog,repl_ex);
- }*/
-
- runtime->nsteps_done = step_rel;
-
- return 0;
-}
-
-
-int mdrunner_membed(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,
- int nstepout,int resetstep,int nmultisim,int repl_ex_nst,int repl_ex_seed,
- real pforce,real cpt_period,real max_hours,
- const char *deviceOptions,
- unsigned long Flags,
- real xy_fac, real xy_max, real z_fac, real z_max,
- int it_xy, int it_z, real probe_rad, int low_up_rm,
- int pieces, gmx_bool bALLOW_ASYMMETRY, int maxwarn)
-{
- double nodetime=0,realtime;
- t_inputrec *inputrec;
- t_state *state=NULL;
- matrix box;
- gmx_ddbox_t ddbox;
- 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=1,nthreads_requested=1;
-
-
- char *ins;
- int rm_bonded_at,fr_id,fr_i=0,tmp_id,warn=0;
- int ng,j,max_lip_rm,ins_grp_id,ins_nat,mem_nat,ntype,lip_rm,tpr_version;
- real xy_step=0,z_step=0;
- real prot_area;
- rvec *r_ins=NULL,fac;
- t_block *ins_at,*rest_at;
- pos_ins_t *pos_ins;
- mem_t *mem_p;
- rm_t *rm_p;
- gmx_groups_t *groups;
- gmx_bool bExcl=FALSE;
- t_atoms atoms;
- t_pbc *pbc;
- char **piecename=NULL;
-
- /* 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 (bVerbose && SIMMASTER(cr))
- {
- fprintf(stderr,"Getting Loaded...\n");
- }
-
- if (Flags & MD_APPENDFILES)
- {
- fplog = NULL;
- }
-
- snew(state,1);
- if (MASTER(cr))
- {
- /* Read (nearly) all data required for the simulation */
- read_tpx_state(ftp2fn(efTPX,nfile,fnm),inputrec,state,NULL,mtop);
-
- /* NOW the threads will be started: */
-#ifdef GMX_THREADS
-#endif
- }
- /* END OF CAUTION: cr is now reliable */
-
- if (PAR(cr))
- {
- /* now broadcast everything to the non-master nodes/threads: */
- init_parallel(fplog, cr, inputrec, mtop);
- }
- /* now make sure the state is initialized and propagated */
- set_state_entries(state,inputrec,cr->nnodes);
-
- if (can_use_allvsall(inputrec,mtop,TRUE,cr,fplog))
- {
- /* All-vs-all loops do not work with domain decomposition */
- Flags |= MD_PARTDEC;
- }
-
- if (!EEL_PME(inputrec->coulombtype) || (Flags & MD_PARTDEC))
- {
- cr->npmenodes = 0;
- }
-
- snew(ins_at,1);
- snew(pos_ins,1);
- if(MASTER(cr))
- {
- tpr_version = get_tpr_version(ftp2fn(efTPX,nfile,fnm));
- if (tpr_version<58)
- gmx_fatal(FARGS,"Version of *.tpr file to old (%d). Rerun grompp with gromacs VERSION 4.0.3 or newer.\n",tpr_version);
-
- if( inputrec->eI != eiMD )
- gmx_input("Change integrator to md in mdp file.");
-
- if(PAR(cr))
- gmx_input("Sorry, parallel g_membed is not yet fully functrional.");
-
- groups=&(mtop->groups);
-
- atoms=gmx_mtop_global_atoms(mtop);
- snew(mem_p,1);
- fprintf(stderr,"\nSelect a group to embed in the membrane:\n");
- get_index(&atoms,ftp2fn_null(efNDX,nfile,fnm),1,&(ins_at->nr),&(ins_at->index),&ins);
- ins_grp_id = search_string(ins,groups->ngrpname,(groups->grpname));
- fprintf(stderr,"\nSelect a group to embed %s into (e.g. the membrane):\n",ins);
- get_index(&atoms,ftp2fn_null(efNDX,nfile,fnm),1,&(mem_p->mem_at.nr),&(mem_p->mem_at.index),&(mem_p->name));
-
- pos_ins->pieces=pieces;
- snew(pos_ins->nidx,pieces);
- snew(pos_ins->subindex,pieces);
- snew(piecename,pieces);
- if (pieces>1)
- {
- fprintf(stderr,"\nSelect pieces to embed:\n");
- get_index(&atoms,ftp2fn_null(efNDX,nfile,fnm),pieces,pos_ins->nidx,pos_ins->subindex,piecename);
- }
- else
- {
- /*use whole embedded group*/
- snew(pos_ins->nidx,1);
- snew(pos_ins->subindex,1);
- pos_ins->nidx[0]=ins_at->nr;
- pos_ins->subindex[0]=ins_at->index;
- }
-
- if(probe_rad<0.2199999)
- {
- warn++;
- fprintf(stderr,"\nWarning %d:\nA probe radius (-rad) smaller than 0.2 can result in overlap between waters "
- "and the group to embed, which will result in Lincs errors etc.\nIf you are sure, you can increase maxwarn.\n\n",warn);
- }
-
- if(xy_fac<0.09999999)
- {
- warn++;
- fprintf(stderr,"\nWarning %d:\nThe initial size of %s is probably too smal.\n"
- "If you are sure, you can increase maxwarn.\n\n",warn,ins);
- }
-
- if(it_xy<1000)
- {
- warn++;
- fprintf(stderr,"\nWarning %d;\nThe number of steps used to grow the xy-coordinates of %s (%d) is probably too small.\n"
- "Increase -nxy or, if you are sure, you can increase maxwarn.\n\n",warn,ins,it_xy);
- }
-
- if( (it_z<100) && ( z_fac<0.99999999 || z_fac>1.0000001) )
- {
- warn++;
- fprintf(stderr,"\nWarning %d;\nThe number of steps used to grow the z-coordinate of %s (%d) is probably too small.\n"
- "Increase -nz or, if you are sure, you can increase maxwarn.\n\n",warn,ins,it_z);
- }
-
- if(it_xy+it_z>inputrec->nsteps)
- {
- warn++;
- fprintf(stderr,"\nWarning %d:\nThe number of growth steps (-nxy + -nz) is larger than the number of steps in the tpr.\n"
- "If you are sure, you can increase maxwarn.\n\n",warn);
- }
-
- fr_id=-1;
- if( inputrec->opts.ngfrz==1)
- gmx_fatal(FARGS,"You did not specify \"%s\" as a freezegroup.",ins);
- for(i=0;i<inputrec->opts.ngfrz;i++)
- {
- tmp_id = mtop->groups.grps[egcFREEZE].nm_ind[i];
- if(ins_grp_id==tmp_id)
- {
- fr_id=tmp_id;
- fr_i=i;
- }
- }
- if (fr_id == -1 )
- gmx_fatal(FARGS,"\"%s\" not as freezegroup defined in the mdp-file.",ins);
-
- for(i=0;i<DIM;i++)
- if( inputrec->opts.nFreeze[fr_i][i] != 1)
- gmx_fatal(FARGS,"freeze dimensions for %s are not Y Y Y\n",ins);
-
- ng = groups->grps[egcENER].nr;
- if (ng == 1)
- gmx_input("No energy groups defined. This is necessary for energy exclusion in the freeze group");
-
- for(i=0;i<ng;i++)
- {
- for(j=0;j<ng;j++)
- {
- if (inputrec->opts.egp_flags[ng*i+j] == EGP_EXCL)
- {
- bExcl = TRUE;
- if ( (groups->grps[egcENER].nm_ind[i] != ins_grp_id) || (groups->grps[egcENER].nm_ind[j] != ins_grp_id) )
- gmx_fatal(FARGS,"Energy exclusions \"%s\" and \"%s\" do not match the group to embed \"%s\"",
- *groups->grpname[groups->grps[egcENER].nm_ind[i]],
- *groups->grpname[groups->grps[egcENER].nm_ind[j]],ins);
- }
- }
- }
- if (!bExcl)
- gmx_input("No energy exclusion groups defined. This is necessary for energy exclusion in the freeze group");
-
- /* Set all atoms in box*/
- /*set_inbox(state->natoms,state->x);*/
-
- /* Guess the area the protein will occupy in the membrane plane Calculate area per lipid*/
- snew(rest_at,1);
- ins_nat = init_ins_at(ins_at,rest_at,state,pos_ins,groups,ins_grp_id,xy_max);
- /* Check moleculetypes in insertion group */
- check_types(ins_at,rest_at,mtop);
-
- mem_nat = init_mem_at(mem_p,mtop,state->x,state->box,pos_ins);
-
- prot_area = est_prot_area(pos_ins,state->x,ins_at,mem_p);
- if ( (prot_area>7.5) && ( (state->box[XX][XX]*state->box[YY][YY]-state->box[XX][YY]*state->box[YY][XX])<50) )
- {
- warn++;
- fprintf(stderr,"\nWarning %d:\nThe xy-area is very small compared to the area of the protein.\n"
- "This might cause pressure problems during the growth phase. Just try with\n"
- "current setup (-maxwarn + 1), but if pressure problems occur, lower the\n"
- "compressibility in the mdp-file or use no pressure coupling at all.\n\n",warn);
- }
- if(warn>maxwarn)
- gmx_fatal(FARGS,"Too many warnings.\n");
-
- printf("The estimated area of the protein in the membrane is %.3f nm^2\n",prot_area);
- printf("\nThere are %d lipids in the membrane part that overlaps the protein.\nThe area per lipid is %.4f nm^2.\n",mem_p->nmol,mem_p->lip_area);
-
- /* Maximum number of lipids to be removed*/
- max_lip_rm=(int)(2*prot_area/mem_p->lip_area);
- printf("Maximum number of lipids that will be removed is %d.\n",max_lip_rm);
-
- printf("\nWill resize the protein by a factor of %.3f in the xy plane and %.3f in the z direction.\n"
- "This resizing will be done with respect to the geometrical center of all protein atoms\n"
- "that span the membrane region, i.e. z between %.3f and %.3f\n\n",xy_fac,z_fac,mem_p->zmin,mem_p->zmax);
-
- /* resize the protein by xy and by z if necessary*/
- snew(r_ins,ins_at->nr);
- init_resize(ins_at,r_ins,pos_ins,mem_p,state->x,bALLOW_ASYMMETRY);
- fac[0]=fac[1]=xy_fac;
- fac[2]=z_fac;
-
- xy_step =(xy_max-xy_fac)/(double)(it_xy);
- z_step =(z_max-z_fac)/(double)(it_z-1);
-
- resize(ins_at,r_ins,state->x,pos_ins,fac);
-
- /* remove overlapping lipids and water from the membrane box*/
- /*mark molecules to be removed*/
- snew(pbc,1);
- set_pbc(pbc,inputrec->ePBC,state->box);
-
- snew(rm_p,1);
- lip_rm = gen_rm_list(rm_p,ins_at,rest_at,pbc,mtop,state->x, r_ins, mem_p,pos_ins,probe_rad,low_up_rm,bALLOW_ASYMMETRY);
- lip_rm -= low_up_rm;
-
- if(fplog)
- for(i=0;i<rm_p->nr;i++)
- fprintf(fplog,"rm mol %d\n",rm_p->mol[i]);
-
- for(i=0;i<mtop->nmolblock;i++)
- {
- ntype=0;
- for(j=0;j<rm_p->nr;j++)
- if(rm_p->block[j]==i)
- ntype++;
- printf("Will remove %d %s molecules\n",ntype,*(mtop->moltype[mtop->molblock[i].type].name));
- }
-
- if(lip_rm>max_lip_rm)
- {
- warn++;
- fprintf(stderr,"\nWarning %d:\nTrying to remove a larger lipid area than the estimated protein area\n"
- "Try making the -xyinit resize factor smaller. If you are sure about this increase maxwarn.\n\n",warn);
- }
-
- /*remove all lipids and waters overlapping and update all important structures*/
- rm_group(inputrec,groups,mtop,rm_p,state,ins_at,pos_ins);
-
- rm_bonded_at = rm_bonded(ins_at,mtop);
- if (rm_bonded_at != ins_at->nr)
- {
- fprintf(stderr,"Warning: The number of atoms for which the bonded interactions are removed is %d, "
- "while %d atoms are embedded. Make sure that the atoms to be embedded are not in the same"
- "molecule type as atoms that are not to be embedded.\n",rm_bonded_at,ins_at->nr);
- }
-
- if(warn>maxwarn)
- gmx_fatal(FARGS,"Too many warnings.\nIf you are sure these warnings are harmless, you can increase -maxwarn");
-
- if (MASTER(cr))
- {
- if (ftp2bSet(efTOP,nfile,fnm))
- top_update(opt2fn("-p",nfile,fnm),ins,rm_p,mtop);
- }
-
- sfree(pbc);
- sfree(rest_at);
- }
-
-#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.
- */
-/* deform_init_init_step_tpx = inputrec->init_step;*/
-/* copy_mat(box,deform_init_box_tpx);*/
- }
-
- 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));
-
- if (bReadRNG)
- {
- Flags |= MD_READ_RNG;
- }
- if (bReadEkin)
- {
- Flags |= MD_READ_EKIN;
- }
- }
- }
-
- if ((MASTER(cr) || (Flags & MD_SEPPOT)) && (Flags & MD_APPENDFILES))
- {
- gmx_log_open(ftp2fn(efLOG,nfile,fnm),cr,!(Flags & MD_SEPPOT),
- Flags,&fplog);
- }
-
- if (SIMMASTER(cr))
- {
- copy_mat(state->box,box);
- }
-
- if (PAR(cr))
- {
- gmx_bcast(sizeof(box),box,cr);
- }
-
- if (bVerbose && SIMMASTER(cr))
- {
- fprintf(stderr,"Loaded with Money\n\n");
- }
-
- if (PAR(cr) && !((Flags & MD_PARTDEC) || EI_TPI(inputrec->eI)))
- {
- 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 = cr->nnodes;
- npme_minor = 1;
-
- 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);
- }
-
- wcycle = wallcycle_init(fplog,resetstep,cr);
- 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))
- {
- if (!MASTER(cr))
- {
- snew(state,1);
- }
- bcast_state(cr,state,TRUE);
- }
- }
-
- /* Dihedral Restraints */
- if (gmx_mtop_ftype_count(mtop,F_DIHRES) > 0)
- {
- init_dihres(fplog,mtop,inputrec,fcd);
- }
-
- /* Initiate forcerecord */
- fr = mk_forcerec();
- init_forcerec(fplog,oenv,fr,fcd,inputrec,mtop,cr,box,FALSE,
- opt2fn("-table",nfile,fnm),
- opt2fn("-tablep",nfile,fnm),
- opt2fn("-tableb",nfile,fnm),FALSE,pforce);
-
- /* version for PCA_NOT_READ_NODE (see md.c) */
- /*init_forcerec(fplog,fr,fcd,inputrec,mtop,cr,box,FALSE,
- "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);
-
- 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);
- }
- }
-
- /* Initiate PPPM if necessary */
- if (fr->eeltype == eelPPPM)
- {
- if (mdatoms->nChargePerturbed)
- {
- gmx_fatal(FARGS,"Free energy with %s is not implemented",
- eel_names[fr->eeltype]);
- }
- status = gmx_pppm_init(fplog,cr,oenv,FALSE,TRUE,box,
- getenv("GMXGHAT"),inputrec, (Flags & MD_REPRODUCIBLE));
- if (status != 0)
- {
- gmx_fatal(FARGS,"Error %d initializing PPPM",status);
- }
- }
-
- 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);
- }
-
- /* 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));
- if (status != 0)
- {
- gmx_fatal(FARGS,"Error %d initializing PME",status);
- }
- }
- }
-
-
-/* if (integrator[inputrec->eI].func == do_md
-#ifdef GMX_OPENMM
- ||
- integrator[inputrec->eI].func == do_md_openmm
-#endif
- )
- {*/
- /* 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,
- EI_DYNAMICS(inputrec->eI) && MASTER(cr),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...) */
- do_md_membed(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_seed,
- cpt_period,max_hours,
- deviceOptions,
- Flags,
- &runtime,
- fac, r_ins, pos_ins, ins_at,
- xy_step, z_step, it_xy, it_z);
-
- if (inputrec->ePull != epullNO)
- {
- finish_pull(fplog,inputrec->pull);
- }
- }
- 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 (MASTER(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,
- EI_DYNAMICS(inputrec->eI) && !MULTISIM(cr));
-
- /* 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);
- }
-
- if (pieces>1)
- {
- sfree(piecename);
- }
-
- rc=(int)gmx_get_stop_condition();
-
- return rc;
-}
-
-
int gmx_membed(int argc,char *argv[])
{
const char *desc[] = {
int maxwarn=0;
int pieces=1;
gmx_bool bALLOW_ASYMMETRY=FALSE;
+ gmx_bool bStart=FALSE;
int nstepout=100;
gmx_bool bVerbose=FALSE;
char *mdrun_path=NULL;
"Number of lipids that will additionally be removed from the lower (negative number) or upper (positive number) membrane leaflet." },
{ "-maxwarn", FALSE, etINT, {&maxwarn},
"Maximum number of warning allowed" },
+ { "-start", FALSE, etBOOL, {&bStart},
+ "Call mdrun with membed options" },
{ "-stepout", FALSE, etINT, {&nstepout},
"HIDDENFrequency of writing the remaining runtime" },
{ "-v", FALSE, etBOOL,{&bVerbose},
}
printf("%s\n",buf);
- system(buf);
+ if (bStart)
+ {
+ system(buf);
+ } else {
+ printf("You can membed your protein now by:\n%s\n",buf);
+ }
fprintf(stderr,"Please cite:\nWolf et al, J Comp Chem 31 (2010) 2169-2174.\n");
const char *desc[] = {
"g_saltbr plots the distance between all combination of charged groups",
"as a function of time. The groups are combined in different ways.",
- "A minimum distance can be given, (eg. the cut-off), then groups",
- "that are never closer than that distance will not be plotted.[BR]",
+ "A truncation/cut-off distance can be supplied with -t, ",
+ "such that only groups interacting within this distance will be plotted in the ",
+ "output.[BR]",
"Output will be in a number of fixed filenames, min-min.xvg, plus-min.xvg",
"and plus-plus.xvg, or files for every individual ion-pair if the [TT]-sep[tt]",
"option is selected. In this case files are named as [TT]sb-ResnameResnr-Atomnr[tt].",
#include <config.h>
#endif
+
+#include <time.h>
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+
+
#include "statutil.h"
#include "typedefs.h"
#include "smalloc.h"
parse_common_args(&argc,argv,PCA_CAN_VIEW | PCA_CAN_TIME | PCA_BE_NICE,
NFILE,fnm,npargs,ppa,asize(desc),desc,0,NULL,&oenv);
- if (bMol)
- bTPS = bM || ftp2bSet(efTPS,NFILE,fnm) || !ftp2bSet(efNDX,NFILE,fnm);
+ if (bMol || bM) {
+ bTPS = ftp2bSet(efTPS,NFILE,fnm) || !ftp2bSet(efNDX,NFILE,fnm);
+ }
if (bTPS) {
bTop=read_tps_conf(ftp2fn(efTPS,NFILE,fnm),title,&top,&ePBC,NULL,NULL,box,
+/* -*- 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
- *
+ *
* VERSION 3.2.0
* Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* 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:
* Green Red Orange Magenta Azure Cyan Skyblue
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
-
-
#include <stdio.h>
#include "statutil.h"
#include "statutil.h"
#include "tpxio.h"
#include "names.h"
+#include "gmx_random.h"
#include "gmx_ana.h"
-
#ifndef HAVE_STRDUP
#define HAVE_STRDUP
#endif
#include "xvgr.h"
+#define WHAM_MAXFILELEN 2048
+
/* enum for energy units */
enum { enSel, en_kJ, en_kCal, en_kT, enNr };
/* enum for type of input files (pdos, tpr, or pullf) */
enum { whamin_unknown, whamin_tpr, whamin_pullxf, whamin_pdo };
-/* enum for methods to make profile cyclic/periodic */
-enum { enCycl, enCycl_no, enCycl_yes, enCycl_weighted, enCycl_nr};
+/* enum for bootstrapping method (
+ - bootstrap complete histograms with continuous weights (Bayesian bootstrap)
+ - bootstrap complete histograms
+ - bootstrap trajectories from given umbrella histograms
+ - bootstrap trajectories from Gaussian with mu/sigam computed from
+ the respective histogram
+
+ ********************************************************************
+ FOR MORE DETAILS ON THE BOOTSTRAP METHODS (INCLUDING EXAMPLES), SEE
+ JS Hub, BL de Groot, D van der Spoel
+ g_wham - A free weighted histogram analysis implementation including
+ robust error and autocorrelation estimates,
+ J Chem Theory Comput, accepted (2010)
+ ********************************************************************
+ */
+enum { bsMethod_unknown, bsMethod_BayesianHist, bsMethod_hist,
+ bsMethod_traj, bsMethod_trajGauss };
+
-typedef struct
+typedef struct
{
- /* umbrella with pull code of gromacs 4 */
+ /* umbrella with pull code of gromacs 4.x */
int npullgrps; /* nr of pull groups in tpr file */
int pull_geometry; /* such as distance, position */
ivec pull_dim; /* pull dimension with geometry distance */
int pull_ndim; /* nr of pull_dim != 0 */
real *k; /* force constants in tpr file */
rvec *init_dist; /* reference displacements */
- real *umbInitDist; /* referebce displacement in umbrella direction */
-
+ real *umbInitDist; /* reference displacement in umbrella direction */
+
/* From here, old pdo stuff */
- int nSkip;
+ int nSkip;
char Reference[256];
int nPull;
int nDim;
char PullName[4][256];
double UmbPos[4][3];
double UmbCons[4][3];
- gmx_bool Flipped[4];
} t_UmbrellaHeader;
-typedef struct
+typedef struct
{
- int nPull;
- int nBin;
- double **Histo,**cum;
- double *k;
- double *pos;
- double *z;
- double * N, *Ntot;
- gmx_bool * Flipped;
- double dt;
- gmx_bool **bContrib;
+ int nPull; /* nr of pull groups in this pdo or pullf/x file */
+ double **Histo,**cum; /* nPull histograms and nPull cumulative distr. funct */
+ int nBin; /* nr of bins. identical to opt->bins */
+ double *k; /* force constants for the nPull groups */
+ double *pos; /* umbrella positions for the nPull groups */
+ double *z; /* z=(-Fi/kT) for the nPull groups. These values are
+ iteratively computed during wham */
+ double *N, *Ntot; /* nr of data points in nPull histograms. N and Ntot
+ only differ if bHistEq==TRUE */
+
+ double *g,*tau,*tausmooth; /* g = 1 + 2*tau[int]/dt where tau is the integrated
+ autocorrelation time. Compare, e.g.
+ Ferrenberg/Swendsen, PRL 63:1195 (1989)
+ Kumar et al, J Comp Chem 13, 1011-1021 (1992), eq. 28 */
+
+ double dt; /* timestep in the input data. Can be adapted with
+ g_wham option -dt */
+ gmx_bool **bContrib; /* TRUE, if any data point of the histogram is within min
+ and max, otherwise FALSE. */
+ real **ztime; /* input data z(t) as a function of time. Required to
+ compute ACTs */
+ real *forceAv; /* average force estimated from average displacement, fAv=dzAv*k
+ Used for integration to guess the potential. */
+ real *aver,*sigma; /* average and stddev of histograms */
+ double *bsWeight; /* for bootstrapping complete histograms with continuous weights */
} t_UmbrellaWindow;
-typedef struct
+
+typedef struct
{
- const char *fnTpr,*fnPullf,*fnPdo,*fnPullx;
- gmx_bool bTpr,bPullf,bPdo,bPullx;
- int bins,cycl;
- gmx_bool verbose,bShift,bAuto,bBoundsOnly;
- gmx_bool bFlipProf;
- real tmin, tmax, dt;
- real Temperature,Tolerance;
- int nBootStrap,histBootStrapBlockLength;
- real dtBootStrap,zProfZero,alpha;
- int bsSeed,stepchange;
- gmx_bool bHistBootStrap,bWeightedCycl,bHistOutOnly;
- gmx_bool bAutobounds,bNoprof;
+ /* INPUT STUFF */
+ const char *fnTpr,*fnPullf;
+ const char *fnPdo,*fnPullx; /* file names of input */
+ gmx_bool bTpr,bPullf,bPdo,bPullx;/* input file types given? */
+ real tmin, tmax, dt; /* only read input within tmin and tmax with dt */
+
+ gmx_bool bInitPotByIntegration; /* before WHAM, guess potential by force integration. Yields
+ 1.5 to 2 times faster convergence */
+ int stepUpdateContrib; /* update contribution table every ... iterations. Accelerates
+ WHAM. */
+
+ /* BASIC WHAM OPTIONS */
+ int bins; /* nr of bins, min, max, and dz of profile */
real min,max,dz;
- gmx_bool bLog;
- int unit;
- real zProf0;
- gmx_bool bProf0Set,bs_verbose;
- gmx_bool bHistEq, bTab;
+ real Temperature,Tolerance; /* temperature, converged when probability changes less
+ than Tolerance */
+ gmx_bool bCycl; /* generate cyclic (periodic) PMF */
+
+ /* OUTPUT CONTROL */
+ gmx_bool bLog; /* energy output (instead of probability) for profile */
+ int unit; /* unit for PMF output kJ/mol or kT or kCal/mol */
+ gmx_bool bSym; /* symmetrize PMF around z=0 after WHAM, useful for
+ membranes etc. */
+ real zProf0; /* after wham, set prof to zero at this z-position
+ When bootstrapping, set zProf0 to a "stable" reference
+ position. */
+ gmx_bool bProf0Set; /* setting profile to 0 at zProf0? */
+
+ gmx_bool bBoundsOnly,bHistOnly; /* determine min and max, or write histograms and exit */
+ gmx_bool bAuto; /* determine min and max automatically but do not exit */
+
+ gmx_bool verbose; /* more noisy wham mode */
+ int stepchange; /* print maximum change in prof after how many interations */
+ output_env_t oenv; /* xvgr options */
+
+ /* AUTOCORRELATION STUFF */
+ gmx_bool bTauIntGiven,bCalcTauInt;/* IACT given or should be calculated? */
+ real sigSmoothIact; /* sigma of Gaussian to smooth ACTs */
+ gmx_bool bAllowReduceIact; /* Allow to reduce ACTs during smoothing. Otherwise
+ ACT are only increased during smoothing */
+ real acTrestart; /* when computing ACT, time between restarting points */
+ gmx_bool bHistEq; /* Enforce the same weight for each umbella window, that is
+ calculate with the same number of data points for
+ each window. That can be reasonable, if the histograms
+ have different length, but due to autocorrelation,
+ a longer simulation should not have larger weightin wham. */
+
+ /* BOOTSTRAPPING STUFF */
+ int nBootStrap; /* nr of bootstraps (50 is usually enough) */
+ int bsMethod; /* if == bsMethod_hist, consider complete histograms as independent
+ data points and, hence, only mix complete histograms.
+ if == bsMethod_BayesianHist, consider complete histograms
+ as independent data points, but assign random weights
+ to the histograms during the bootstrapping ("Bayesian bootstrap")
+ In case of long correlations (e.g., inside a channel), these
+ will yield a more realistic error.
+ if == bsMethod_traj(Gauss), generate synthetic histograms
+ for each given
+ histogram by generating an autocorrelated random sequence
+ that is distributed according to the respective given
+ histogram. With bsMethod_trajGauss, bootstrap from a Gaussian
+ (instead of from the umbrella histogram) to generate a new
+ histogram
+ */
+ real tauBootStrap; /* autocorrelation time (ACT) used to generate synthetic
+ histograms. If ==0, use calculated ACF */
+ int histBootStrapBlockLength; /* when mixing histograms, mix only histograms withing blocks
+ long the reaction coordinate xi. Avoids gaps along xi. */
+ int bsSeed; /* random seed for bootstrapping */
+ gmx_bool bs_verbose; /* Write cumulative distribution functions (CDFs) of histograms
+ and write the generated histograms for each bootstrap */
+
+ /* tabulated umbrella potential stuff */
+ gmx_bool bTab;
double *tabX,*tabY,tabMin,tabMax,tabDz;
int tabNbins;
+
+ gmx_rng_t rng; /* gromacs random number generator */
} t_UmbrellaOptions;
+t_UmbrellaWindow * initUmbrellaWindows(int nwin)
+{
+ t_UmbrellaWindow *win;
+ int i;
+ snew(win,nwin);
+ for (i=0; i<nwin; i++)
+ {
+ win[i].Histo = win[i].cum = 0;
+ win[i].k = win[i].pos = win[i].z =0;
+ win[i].N = win[i].Ntot = 0;
+ win[i].g = win[i].tau = win[i].tausmooth = 0;
+ win[i].bContrib=0;
+ win[i].ztime=0;
+ win[i].forceAv=0;
+ win[i].aver = win[i].sigma = 0;
+ win[i].bsWeight = 0;
+ }
+ return win;
+}
+
+void freeUmbrellaWindows(t_UmbrellaWindow *win, int nwin)
+{
+ int i,j;
+ for (i=0; i<nwin; i++)
+ {
+ if (win[i].Histo)
+ for (j=0;j<win[i].nPull;j++)
+ sfree(win[i].Histo[j]);
+ if (win[i].cum)
+ for (j=0;j<win[i].nPull;j++)
+ sfree(win[i].cum[j]);
+ if (win[i].bContrib)
+ for (j=0;j<win[i].nPull;j++)
+ sfree(win[i].bContrib[j]);
+ sfree(win[i].Histo);
+ sfree(win[i].cum);
+ sfree(win[i].k);
+ sfree(win[i].pos);
+ sfree(win[i].z);
+ sfree(win[i].N);
+ sfree(win[i].Ntot);
+ sfree(win[i].g);
+ sfree(win[i].tau);
+ sfree(win[i].tausmooth);
+ sfree(win[i].bContrib);
+ sfree(win[i].ztime);
+ sfree(win[i].forceAv);
+ sfree(win[i].aver);
+ sfree(win[i].sigma);
+ sfree(win[i].bsWeight);
+ }
+ sfree(win);
+}
+
/* Return j such that xx[j] <= x < xx[j+1] */
void searchOrderedTable(double xx[], int n, double x, int *j)
{
int ju,jm,jl;
int ascending;
-
-
+
jl=-1;
ju=n;
ascending=(xx[n-1] > xx[0]);
- while (ju-jl > 1)
+ while (ju-jl > 1)
{
jm=(ju+jl) >> 1;
if ((x >= xx[jm]) == ascending)
else *j=jl;
}
-
/* Read and setup tabulated umbrella potential */
void setup_tab(const char *fn,t_UmbrellaOptions *opt)
{
int i,ny,nl;
double **y;
-
-
+
printf("Setting up tabulated potential from file %s\n",fn);
nl=read_xvg(fn,&y,&ny);
opt->tabNbins=nl;
opt->tabDz=(opt->tabMax-opt->tabMin)/(nl-1);
if (opt->tabDz<=0)
gmx_fatal(FARGS,"The tabulated potential in %s must be provided in \n"
- "ascending z-direction",fn);
+ "ascending z-direction",fn);
for (i=0;i<nl-1;i++)
if (fabs(y[0][i+1]-y[0][i]-opt->tabDz) > opt->tabDz/1e6)
gmx_fatal(FARGS,"z-values in %s are not equally spaced.\n",ny,fn);
snew(opt->tabY,nl);
snew(opt->tabX,nl);
- for (i=0;i<nl;i++){
+ for (i=0;i<nl;i++)
+ {
opt->tabX[i]=y[0][i];
opt->tabY[i]=y[1][i];
}
printf("Found equally spaced tabulated potential from %g to %g, spacing %g\n",
- opt->tabMin,opt->tabMax,opt->tabDz);
+ opt->tabMin,opt->tabMax,opt->tabDz);
}
-
-void read_pdo_header(FILE * file,t_UmbrellaHeader * header,
- t_UmbrellaOptions *opt)
+void read_pdo_header(FILE * file,t_UmbrellaHeader * header, t_UmbrellaOptions *opt)
{
- char Buffer0[256];
- char Buffer1[256];
- char Buffer2[256];
- char Buffer3[256];
- char Buffer4[256];
- int i,j;
-
-
+ char line[2048];
+ char Buffer0[256], Buffer1[256], Buffer2[256], Buffer3[256], Buffer4[256];
+ int i;
+
/* line 1 */
- if(3 != fscanf(file,"%s%s%s",Buffer0,Buffer1,Buffer2))
- {
- gmx_fatal(FARGS,"Error reading header from pdo file");
- }
- if(strcmp(Buffer1,"UMBRELLA"))
- gmx_fatal(FARGS,"This does not appear to be a valid pdo file. Found %s, expected %s",
- Buffer1, "UMBRELLA");
+ if (fgets(line,2048,file) == NULL)
+ gmx_fatal(FARGS,"Error reading header from pdo file\n");
+ sscanf(line,"%s%s%s",Buffer0,Buffer1,Buffer2);
+ if(strcmp(Buffer1,"UMBRELLA"))
+ gmx_fatal(FARGS,"This does not appear to be a valid pdo file. Found %s, expected %s\n"
+ "(Found in first line: `%s')\n",
+ Buffer1, "UMBRELLA",line);
if(strcmp(Buffer2,"3.0"))
gmx_fatal(FARGS,"This does not appear to be a version 3.0 pdo file");
-
+
/* line 2 */
- if(6 != fscanf(file,"%s%s%s%d%d%d",Buffer0,Buffer1,Buffer2,
- &(header->Dims[0]),&(header->Dims[1]),&(header->Dims[2])))
- {
- gmx_fatal(FARGS,"Error reading dimensions in header from pdo file");
- }
-
+ if (fgets(line,2048,file) == NULL)
+ gmx_fatal(FARGS,"Error reading header from pdo file\n");
+ sscanf(line,"%s%s%s%d%d%d",Buffer0,Buffer1,Buffer2,
+ &(header->Dims[0]),&(header->Dims[1]),&(header->Dims[2]));
+
/* printf("%d %d %d\n", header->Dims[0],header->Dims[1],header->Dims[2]); */
-
+
header->nDim = header->Dims[0] + header->Dims[1] + header->Dims[2];
if(header->nDim!=1)
gmx_fatal(FARGS,"Currently only supports one dimension");
-
+
/* line3 */
- if(3 != fscanf(file,"%s%s%d",Buffer0,Buffer1,&(header->nSkip)))
- {
- gmx_fatal(FARGS,"Error reading header from pdo file");
- }
-
- /* line 4 */
- if(4 != fscanf(file,"%s%s%s%s",Buffer0,Buffer1,Buffer2,header->Reference))
- {
- gmx_fatal(FARGS,"Error reading header from pdo file");
- }
-
+ if (fgets(line,2048,file) == NULL)
+ gmx_fatal(FARGS,"Error reading header from pdo file\n");
+ sscanf(line,"%s%s%d",Buffer0,Buffer1,&(header->nSkip));
+
+ /* line 4 */
+ if (fgets(line,2048,file) == NULL)
+ gmx_fatal(FARGS,"Error reading header from pdo file\n");
+ sscanf(line,"%s%s%s%s",Buffer0,Buffer1,Buffer2,header->Reference);
+
/* line 5 */
- if(6 != fscanf(file,"%s%s%s%s%s%d",Buffer0,Buffer1,Buffer2,Buffer3,Buffer4,&(header->nPull)))
- {
- gmx_fatal(FARGS,"Error reading header from pdo file");
- }
-
+ if (fgets(line,2048,file) == NULL)
+ gmx_fatal(FARGS,"Error reading header from pdo file\n");
+ sscanf(line,"%s%s%s%s%s%d",Buffer0,Buffer1,Buffer2,Buffer3,Buffer4,&(header->nPull));
+
if (opt->verbose)
- printf("Found nPull=%d , nSkip=%d, ref=%s\n",header->nPull,header->nSkip,
- header->Reference);
-
- for(i=0;i<header->nPull;++i)
+ printf("\tFound nPull=%d , nSkip=%d, ref=%s\n",header->nPull,header->nSkip,
+ header->Reference);
+
+ for(i=0;i<header->nPull;++i)
{
- if(4 != fscanf(file,"%s%s%s%s",Buffer0,Buffer1,Buffer2,header->PullName[i]))
- {
- gmx_fatal(FARGS,"Error reading header from pdo file");
- }
+ if (fgets(line,2048,file) == NULL)
+ gmx_fatal(FARGS,"Error reading header from pdo file\n");
+ sscanf(line,"%*s%*s%*s%s%*s%*s%lf%*s%*s%lf",header->PullName[i]
+ ,&(header->UmbPos[i][0]),&(header->UmbCons[i][0]));
if (opt->verbose)
- printf("pullgroup %d, pullname = %s\n",i,header->PullName[i]);
- for(j=0;j<header->nDim;++j)
- {
- if(6 != fscanf(file,"%s%s%lf%s%s%lf",Buffer0,Buffer1,&(header->UmbPos[i][j]),
- Buffer2,Buffer3,&(header->UmbCons[i][j])))
- {
- gmx_fatal(FARGS,"Error reading header from pdo file");
- }
-
- if (opt->bFlipProf)
- {
- /* We want to combine both halves of a profile into one */
- if(header->UmbPos[i][j]<0)
- {
- header->UmbPos[i][j]= -header->UmbPos[i][j];
- header->Flipped[i]=TRUE;
- }
- }
- else header->Flipped[i]=FALSE;
- /*printf("%f\t%f\n",header->UmbPos[i][j],header->UmbCons[i][j]);*/
- }
- }
-
- if(1 != fscanf(file,"%s",Buffer3))
- {
- gmx_fatal(FARGS,"Error reading header from pdo file");
+ printf("\tpullgroup %d, pullname = %s, UmbPos = %g, UmbConst = %g\n",
+ i,header->PullName[i],header->UmbPos[i][0],header->UmbCons[i][0]);
}
-
+
+ if (fgets(line,2048,file) == NULL)
+ gmx_fatal(FARGS,"Cannot read from file\n");
+ sscanf(line,"%s",Buffer3);
if (strcmp(Buffer3,"#####") != 0)
gmx_fatal(FARGS,"Expected '#####', found %s. Hick.\n",Buffer3);
}
{
char *p;
int slen;
-
-
+
if (fgets(ptr,*len-1,fp) == NULL)
return NULL;
p = ptr;
- while ((strchr(ptr,'\n') == NULL) && (!feof(fp)))
+ while ((strchr(ptr,'\n') == NULL) && (!feof(fp)))
{
/* This line is longer than len characters, let's increase len! */
*len += STRLEN;
slen = strlen(ptr);
if (ptr[slen-1] == '\n')
ptr[slen-1] = '\0';
-
+
return ptr;
}
-
void read_pdo_data(FILE * file, t_UmbrellaHeader * header,
- int fileno, t_UmbrellaWindow * win,
- t_UmbrellaOptions *opt,
- gmx_bool bGetMinMax,real *mintmp,real *maxtmp)
+ int fileno, t_UmbrellaWindow * win,
+ t_UmbrellaOptions *opt,
+ gmx_bool bGetMinMax,real *mintmp,real *maxtmp)
{
- int i,inttemp,bins,count;
- real min,max,minfound,maxfound;
+ int i,inttemp,bins,count,ntot;
+ real min,max,minfound=1e20,maxfound=-1e20;
double temp,time,time0=0,dt;
- char *ptr;
+ char *ptr=0;
t_UmbrellaWindow * window=0;
gmx_bool timeok,dt_ok=1;
- char *tmpbuf,fmt[256],fmtign[256];
- int len=STRLEN,dstep=1;
-
- minfound=1e20;
- maxfound=-1e20;
-
+ char *tmpbuf=0,fmt[256],fmtign[256];
+ int len=STRLEN,dstep=1;
+ const int blocklen=4096;
+ int *lennow=0;
+
if (!bGetMinMax)
{
bins=opt->bins;
min=opt->min;
max=opt->max;
-
+
window=win+fileno;
/* Need to alocate memory and set up structure */
window->nPull=header->nPull;
window->nBin=bins;
-
+
snew(window->Histo,window->nPull);
snew(window->z,window->nPull);
snew(window->k,window->nPull);
snew(window->pos,window->nPull);
- snew(window->Flipped,window->nPull);
snew(window->N, window->nPull);
snew(window->Ntot, window->nPull);
-
- for(i=0;i<window->nPull;++i)
+ snew(window->g, window->nPull);
+ snew(window->bsWeight, window->nPull);
+
+ window->bContrib=0;
+
+ if (opt->bCalcTauInt)
+ snew(window->ztime, window->nPull);
+ else
+ window->ztime=0;
+ snew(lennow,window->nPull);
+
+ for(i=0;i<window->nPull;++i)
{
window->z[i]=1;
+ window->bsWeight[i]=1.;
snew(window->Histo[i],bins);
window->k[i]=header->UmbCons[i][0];
window->pos[i]=header->UmbPos[i][0];
- window->Flipped[i]=header->Flipped[i];
window->N[i]=0;
window->Ntot[i]=0;
+ window->g[i]=1.;
+ if (opt->bCalcTauInt)
+ window->ztime[i]=0;
}
+
/* Done with setup */
}
else
maxfound=-1e20;
min=max=bins=0; /* Get rid of warnings */
}
-
+
count=0;
snew(tmpbuf,len);
while ( (ptr=fgets3(file,tmpbuf,&len)) != NULL)
{
trim(ptr);
-
+
if (ptr[0] == '#' || strlen(ptr)<2)
continue;
-
+
/* Initiate format string */
fmtign[0] = '\0';
strcat(fmtign,"%*s");
-
+
sscanf(ptr,"%lf",&time); /* printf("Time %f\n",time); */
/* Round time to fs */
time=1.0/1000*( (int) (time*1000+0.5) );
-
+
/* get time step of pdo file */
if (count==0)
time0=time;
dt=time-time0;
if (opt->dt>0.0)
{
- dstep=(int)(opt->dt/dt+0.5);
+ dstep=(int)(opt->dt/dt+0.5);
if (dstep==0)
dstep=1;
}
window->dt=dt*dstep;
}
count++;
-
+
dt_ok=((count-1)%dstep == 0);
timeok=(dt_ok && time >= opt->tmin && time <= opt->tmax);
/* if (opt->verbose)
- printf(" time = %f, (tmin,tmax)=(%e,%e), dt_ok=%d timeok=%d\n",
- time,opt->tmin, opt->tmax, dt_ok,timeok); */
-
+ printf(" time = %f, (tmin,tmax)=(%e,%e), dt_ok=%d timeok=%d\n",
+ time,opt->tmin, opt->tmax, dt_ok,timeok); */
+
if (timeok)
{
- for(i=0;i<header->nPull;++i)
+ for(i=0;i<header->nPull;++i)
{
strcpy(fmt,fmtign);
strcat(fmt,"%lf"); /* Creating a format stings such as "%*s...%*s%lf" */
strcat(fmtign,"%*s"); /* ignoring one more entry in the next loop */
- if(sscanf(ptr,fmt,&temp))
+ if(sscanf(ptr,fmt,&temp))
{
- if(opt->bFlipProf)
- {
- if(header->Flipped[i]) temp=-temp;
- }
-
temp+=header->UmbPos[i][0];
- if (bGetMinMax){
+ if (bGetMinMax)
+ {
if (temp<minfound)
minfound=temp;
if (temp>maxfound)
maxfound=temp;
}
- else
- {
+ else{
+ if (opt->bCalcTauInt)
+ {
+ /* save time series for autocorrelation analysis */
+ ntot=window->Ntot[i];
+ if (ntot>=lennow[i])
+ {
+ lennow[i]+=blocklen;
+ srenew(window->ztime[i],lennow[i]);
+ }
+ window->ztime[i][ntot]=temp;
+ }
+
temp-=min;
temp/=(max-min);
temp*=bins;
temp=floor(temp);
-
+
inttemp = (int)temp;
- if (opt->cycl==enCycl_yes)
+ if (opt->bCycl)
{
if (inttemp < 0)
inttemp+=bins;
else if (inttemp >= bins)
inttemp-=bins;
}
-
- if(inttemp >= 0 && inttemp < bins)
+
+ if(inttemp >= 0 && inttemp < bins)
{
- window->Histo[i][inttemp]+=1;
+ window->Histo[i][inttemp]+=1.;
window->N[i]++;
}
window->Ntot[i]++;
}
- }
+ }
}
}
if (time>opt->tmax)
break;
}
}
-
+
if (bGetMinMax)
{
*mintmp=minfound;
*maxtmp=maxfound;
}
+
+ sfree(lennow);
+ sfree(tmpbuf);
}
-
void enforceEqualWeights(t_UmbrellaWindow * window,int nWindows)
{
int i,k,j,NEnforced;
double ratio;
-
-
+
NEnforced=window[0].Ntot[0];
printf("\nFound -hist-eq. Enforcing equal weights for all histograms, \ni.e. doing a "
- "non-weighted histogram analysis method. Ndata = %d\n",NEnforced);
+ "non-weighted histogram analysis method. Ndata = %d\n",NEnforced);
/* enforce all histograms to have the same weight as the very first histogram */
-
+
for(j=0;j<nWindows;++j)
- for(k=0;k<window[j].nPull;++k)
+ {
+ for(k=0;k<window[j].nPull;++k)
{
ratio=1.0*NEnforced/window[j].Ntot[k];
for(i=0;i<window[0].nBin;++i)
+ {
window[j].Histo[k][i]*=ratio;
- window[j].N[k]=(int)(ratio*window[j].N[k]+0.5);
+ }
+ window[j].N[k]=(int)(ratio*window[j].N[k] + 0.5);
}
+ }
}
-
/* Simple linear interpolation between two given tabulated points */
double tabulated_pot(double dist, t_UmbrellaOptions *opt)
{
int jl,ju;
double pl,pu,dz,dp;
-
jl=floor((dist-opt->tabMin)/opt->tabDz);
ju=jl+1;
if (jl<0 || ju>=opt->tabNbins)
+ {
gmx_fatal(FARGS,"Distance %f out of bounds of tabulated potential (jl=%d, ju=%d).\n"
- "Provide an extended table.",dist,jl,ju);
+ "Provide an extended table.",dist,jl,ju);
+ }
pl=opt->tabY[jl];
pu=opt->tabY[ju];
dz=dist-opt->tabX[jl];
/* Don't worry, that routine does not mean we compute the PMF in limited precision.
- After rapid convergence (using only substiantal contributions), we always switch to
+ After rapid convergence (using only substiantal contributions), we always switch to
full precision. */
-#define WHAM_CONTRIB_LIM 1e-10
-void setup_acc_wham(t_UmbrellaWindow * window,int nWindows, t_UmbrellaOptions *opt)
+void setup_acc_wham(double *profile,t_UmbrellaWindow * window,int nWindows,
+ t_UmbrellaOptions *opt)
{
- int i,j,k;
- double U,min=opt->min,dz=opt->dz,temp,ztot_half,distance,ztot,contrib;
+ int i,j,k,nGrptot=0,nContrib=0,nTot=0;
+ double U,min=opt->min,dz=opt->dz,temp,ztot_half,distance,ztot,contrib1,contrib2;
gmx_bool bAnyContrib;
-
-
+ static int bFirst=1;
+ static double wham_contrib_lim;
+
+ if (bFirst)
+ {
+ for(i=0;i<nWindows;++i)
+ {
+ nGrptot+=window[i].nPull;
+ }
+ wham_contrib_lim=opt->Tolerance/nGrptot;
+ }
+
ztot=opt->max-opt->min;
ztot_half=ztot/2;
-
- for(i=0;i<nWindows;++i)
+
+ for(i=0;i<nWindows;++i)
{
- snew(window[i].bContrib,window[i].nPull);
- for(j=0;j<window[i].nPull;++j)
+ if ( ! window[i].bContrib)
+ {
+ snew(window[i].bContrib,window[i].nPull);
+ }
+ for(j=0;j<window[i].nPull;++j)
{
- snew(window[i].bContrib[j],opt->bins);
+ if ( ! window[i].bContrib[j])
+ snew(window[i].bContrib[j],opt->bins);
bAnyContrib=FALSE;
- for(k=0;k<opt->bins;++k)
+ for(k=0;k<opt->bins;++k)
{
temp=(1.0*k+0.5)*dz+min;
distance = temp - window[i].pos[j]; /* distance to umbrella center */
- if (opt->cycl==enCycl_yes)
+ if (opt->bCycl)
{ /* in cyclic wham: */
if (distance > ztot_half) /* |distance| < ztot_half */
distance-=ztot;
else if (distance < -ztot_half)
distance+=ztot;
}
+ /* Note: there are two contributions to bin k in the wham equations:
+ i) N[j]*exp(- U/(8.314e-3*opt->Temperature) + window[i].z[j])
+ ii) exp(- U/(8.314e-3*opt->Temperature))
+ where U is the umbrella potential
+ If any of these number is larger wham_contrib_lim, I set contrib=TRUE
+ */
+
if (!opt->bTab)
U=0.5*window[i].k[j]*sqr(distance); /* harmonic potential assumed. */
else
U=tabulated_pot(distance,opt); /* Use tabulated potential */
-
- contrib=exp(- U/(8.314e-3*opt->Temperature));
- window[i].bContrib[j][k] = (contrib > WHAM_CONTRIB_LIM);
+
+ contrib1=profile[k]*exp(- U/(8.314e-3*opt->Temperature));
+ contrib2=window[i].N[j]*exp(- U/(8.314e-3*opt->Temperature) + window[i].z[j]);
+ window[i].bContrib[j][k] = (contrib1 > wham_contrib_lim || contrib2 > wham_contrib_lim);
bAnyContrib = (bAnyContrib | window[i].bContrib[j][k]);
+ if (window[i].bContrib[j][k])
+ nContrib++;
+ nTot++;
}
/* If this histo is far outside min and max all bContrib may be FALSE,
- * causing a floating point exception later on. To avoid that, switch
- * them all to true.*/
+ causing a floating point exception later on. To avoid that, switch
+ them all to true.*/
if (!bAnyContrib)
for(k=0;k<opt->bins;++k)
window[i].bContrib[j][k]=TRUE;
}
}
- printf("Initialized rapid wham stuff.\n");
+ if (bFirst)
+ printf("Initialized rapid wham stuff (contrib tolerance %g)\n"
+ "Evaluating only %d of %d expressions.\n\n",wham_contrib_lim,nContrib, nTot);
+
+ if (opt->verbose)
+ printf("Updated rapid wham stuff. (evaluating only %d of %d contributions)\n",
+ nContrib,nTot);
+ bFirst=0;
}
-void calc_profile(double *profile,t_UmbrellaWindow * window, int nWindows, t_UmbrellaOptions *opt,
- gmx_bool bExact)
+void calc_profile(double *profile,t_UmbrellaWindow * window, int nWindows,
+ t_UmbrellaOptions *opt, gmx_bool bExact)
{
int i,k,j;
double num,ztot_half,ztot,distance,min=opt->min,dz=opt->dz;
- double denom,U=0,temp=0;
-
-
+ double denom,U=0,temp=0,invg;
+
ztot=opt->max-opt->min;
- ztot_half=ztot/2;
-
-
- for(i=0;i<opt->bins;++i)
+ ztot_half=ztot/2;
+
+ for(i=0;i<opt->bins;++i)
{
- num=denom=0;
- for(j=0;j<nWindows;++j)
+ num=denom=0.;
+ for(j=0;j<nWindows;++j)
{
- for(k=0;k<window[j].nPull;++k)
+ for(k=0;k<window[j].nPull;++k)
{
- temp=(1.0*i+0.5)*dz+min;
- num+=window[j].Histo[k][i];
-
+ invg = 1.0/window[j].g[k] * window[j].bsWeight[k];
+ temp = (1.0*i+0.5)*dz+min;
+ num += invg*window[j].Histo[k][i];
+
if (! (bExact || window[j].bContrib[k][i]))
continue;
distance = temp - window[j].pos[k]; /* distance to umbrella center */
- if (opt->cycl==enCycl_yes){ /* in cyclic wham: */
+ if (opt->bCycl)
+ { /* in cyclic wham: */
if (distance > ztot_half) /* |distance| < ztot_half */
distance-=ztot;
else if (distance < -ztot_half)
distance+=ztot;
}
-
+
if (!opt->bTab)
U=0.5*window[j].k[k]*sqr(distance); /* harmonic potential assumed. */
else
U=tabulated_pot(distance,opt); /* Use tabulated potential */
- denom+=window[j].N[k]*exp(- U/(8.314e-3*opt->Temperature) + window[j].z[k]);
+ denom+=invg*window[j].N[k]*exp(- U/(8.314e-3*opt->Temperature) + window[j].z[k]);
}
}
profile[i]=num/denom;
}
-double calc_z(double * profile,t_UmbrellaWindow * window, int nWindows, t_UmbrellaOptions *opt,
- gmx_bool bExact)
+double calc_z(double * profile,t_UmbrellaWindow * window, int nWindows,
+ t_UmbrellaOptions *opt, gmx_bool bExact)
{
- int i,j,k;
- double U=0,min=opt->min,dz=opt->dz,temp,ztot_half,distance,ztot;
+ int i,j,k,binMax=-1;
+ double U=0,min=opt->min,dz=opt->dz,temp,ztot_half,distance,ztot,totalMax;
double MAX=-1e20, total=0;
-
-
+
ztot=opt->max-opt->min;
ztot_half=ztot/2;
-
- for(i=0;i<nWindows;++i)
+
+ for(i=0;i<nWindows;++i)
{
- for(j=0;j<window[i].nPull;++j)
+ for(j=0;j<window[i].nPull;++j)
{
total=0;
- for(k=0;k<window[i].nBin;++k)
+ for(k=0;k<window[i].nBin;++k)
{
if (! (bExact || window[i].bContrib[j][k]))
continue;
temp=(1.0*k+0.5)*dz+min;
distance = temp - window[i].pos[j]; /* distance to umbrella center */
- if (opt->cycl==enCycl_yes)
+ if (opt->bCycl)
{ /* in cyclic wham: */
if (distance > ztot_half) /* |distance| < ztot_half */
distance-=ztot;
else if (distance < -ztot_half)
distance+=ztot;
}
-
+
if (!opt->bTab)
U=0.5*window[i].k[j]*sqr(distance); /* harmonic potential assumed. */
else
U=tabulated_pot(distance,opt); /* Use tabulated potential */
-
+
total+=profile[k]*exp(-U/(8.314e-3*opt->Temperature));
}
- if (total > 0.0)
+ /* Avoid floating point exception if window is far outside min and max */
+ if (total != 0.0)
total = -log(total);
else
total = 1000.0;
temp = fabs(total - window[i].z[j]);
- if(temp > MAX) MAX=temp;
+ if(temp > MAX){
+ MAX=temp;
+ binMax=k;
+ totalMax=total;
+ }
window[i].z[j] = total;
}
}
return MAX;
}
-
-void cyclicProfByWeightedCorr(double *profile,t_UmbrellaWindow *window,
- int nWindows, t_UmbrellaOptions * opt,
- gmx_bool bAppendCorr2File, const char *fn,
- const output_env_t oenv)
+void symmetrizeProfile(double* profile,t_UmbrellaOptions *opt)
{
- int i,j,k,bins=opt->bins;
- static int first=1;
- double *weight,sum=0.,diff,*histsum,*corr,sumCorr=0.,dCorr;
- FILE *fp;
- char buf[256];
-
- if (first)
- {
- printf("\nEnforcing a periodic profile by a sampling wheighted correction.");
- please_cite(stdout,"Hub2008");
- }
-
- snew(weight,bins-1);
- snew(histsum,bins);
- snew(corr,bins-1);
-
- /* generate weights proportional to 1/(n(i)*n(i+1))^alpha
- where n(i) is the total nur of data points in bin i from all histograms */
- for(i=0;i<nWindows;++i)
- for(j=0;j<window[i].nPull;++j)
- for(k=0;k<bins;++k)
- histsum[k]+=window[i].Histo[j][k];
-
- for(k=0,sum=0.;k<bins-1;++k)
- {
- weight[k]=1./pow(histsum[k]*histsum[k+1],opt->alpha);
- sum+=weight[k];
- }
- for(k=0;k<bins-1;++k)
- weight[k]/=sum;
-
- /* difference between last and first bin */
- diff=profile[bins-1]-profile[0];
- printf("Distributing %f between adjacent bins to enforce a cyclic profile\n",diff);
-
- for (i=0;i<bins-1;i++)
- {
- dCorr=weight[i]*diff;
- sumCorr+=dCorr;
- corr[i]=sumCorr;
- }
-
- for (i=0;i<bins-1;i++)
- profile[i+1]-=corr[i];
-
- if (bAppendCorr2File)
+ int i,j;
+ double *prof2,bins=opt->bins,min=opt->min,max=opt->max,dz=opt->dz,zsym,deltaz,profsym;
+ double z,z1;
+
+ if (min>0. || max<0.)
+ gmx_fatal(FARGS,"Cannot symmetrize profile around z=0 with min=%f and max=%f\n",
+ opt->min,opt->max);
+
+ snew(prof2,bins);
+
+ for (i=0;i<bins;i++)
{
- fp=xvgropen(fn,"Corrections to enforce periodicity","z",
- "\\f{12}D\\f{}G(z)",oenv);
- sprintf(buf,"corrections propotional to 1/(n\\si\\Nn\\si+1\\N)\\S%.2f",
- opt->alpha);
- xvgr_subtitle(fp,buf,oenv);
- for (i=0;i<bins-1;i++)
- fprintf(fp,"%g %g\n",opt->min+opt->dz*(i+1),-corr[i]);
- ffclose(fp);
+ z=min+(i+0.5)*dz;
+ zsym=-z;
+ /* bin left of zsym */
+ j=floor((zsym-min)/dz-0.5);
+ if (j>=0 && (j+1)<bins)
+ {
+ /* interpolate profile linearly between bins j and j+1 */
+ z1=min+(j+0.5)*dz;
+ deltaz=zsym-z1;
+ profsym=profile[j] + (profile[j+1]-profile[j])/dz*deltaz;
+ /* average between left and right */
+ prof2[i]=0.5*(profsym+profile[i]);
+ }
+ else
+ {
+ prof2[i]=profile[i];
+ }
}
-
- sfree(histsum);
- sfree(corr);
- sfree(weight);
- first=0;
+
+ memcpy(profile,prof2,bins*sizeof(double));
+ sfree(prof2);
}
-
void prof_normalization_and_unit(double * profile, t_UmbrellaOptions *opt)
{
int i,bins,imin;
double unit_factor=1., R_MolarGasConst, diff;
-
-
+
R_MolarGasConst=8.314472e-3; /* in kJ/(mol*K) */
bins=opt->bins;
-
- /* No log? Nothing to do! */
+
+ /* Not log? Nothing to do! */
if (!opt->bLog)
return;
-
+
/* Get profile in units of kT, kJ/mol, or kCal/mol */
if (opt->unit == en_kT)
unit_factor=1.0;
else if (opt->unit == en_kCal)
unit_factor=R_MolarGasConst*opt->Temperature/4.1868;
else
- gmx_fatal(FARGS,"Sorry I don't know this energy unit.");
-
+ gmx_fatal(FARGS,"Sorry, I don't know this energy unit.");
+
for (i=0;i<bins;i++)
if (profile[i]>0.0)
profile[i]=-log(profile[i])*unit_factor;
-
+
/* shift to zero at z=opt->zProf0 */
if (!opt->bProf0Set)
+ {
diff=profile[0];
- else{
- /* Get bin with shortest distance to opt->zProf0 */
- imin=(int)((opt->zProf0-opt->min)/opt->dz);
+ }
+ else
+ {
+ /* Get bin with shortest distance to opt->zProf0
+ (-0.5 from bin position and +0.5 from rounding cancel) */
+ imin=(int)((opt->zProf0-opt->min)/opt->dz);
if (imin<0)
imin=0;
else if (imin>=bins)
imin=bins-1;
diff=profile[imin];
}
-
+
/* Shift to zero */
for (i=0;i<bins;i++)
profile[i]-=diff;
}
-
-void getRandomIntArray(int nPull,int blockLength,int* randomArray)
+void getRandomIntArray(int nPull,int blockLength,int* randomArray,gmx_rng_t rng)
{
int ipull,blockBase,nr,ipullRandom;
-
-
+
if (blockLength==0)
blockLength=nPull;
-
+
for (ipull=0; ipull<nPull; ipull++)
{
blockBase=(ipull/blockLength)*blockLength;
- do{ /* make sure nothing bad happens in the last block */
- nr=(int)((1.0*rand()/RAND_MAX)*blockLength);
+ do
+ { /* make sure nothing bad happens in the last block */
+ nr=(int)(gmx_rng_uniform_real(rng)*blockLength);
ipullRandom = blockBase + nr;
} while (ipullRandom >= nPull);
if (ipullRandom<0 || ipullRandom>=nPull)
gmx_fatal(FARGS,"Ups, random iWin = %d, nPull = %d, nr = %d, "
- "blockLength = %d, blockBase = %d\n",
- ipullRandom,nPull,nr,blockLength,blockBase);
+ "blockLength = %d, blockBase = %d\n",
+ ipullRandom,nPull,nr,blockLength,blockBase);
randomArray[ipull]=ipullRandom;
}
/*for (ipull=0; ipull<nPull; ipull++)
- printf("%d ",randomArray[ipull]); printf("\n"); */
+ printf("%d ",randomArray[ipull]); printf("\n"); */
}
-
void copy_pullgrp_to_synthwindow(t_UmbrellaWindow *synthWindow,
- t_UmbrellaWindow *thisWindow,int pullid)
+ t_UmbrellaWindow *thisWindow,int pullid)
{
synthWindow->N [0]=thisWindow->N [pullid];
synthWindow->Histo [0]=thisWindow->Histo [pullid];
synthWindow->z [0]=thisWindow->z [pullid];
synthWindow->k [0]=thisWindow->k [pullid];
synthWindow->bContrib[0]=thisWindow->bContrib [pullid];
+ synthWindow->g [0]=thisWindow->g [pullid];
+ synthWindow->bsWeight[0]=thisWindow->bsWeight [pullid];
}
-
-/* Calculate cummulative of all histograms. They allow to create random numbers
+/* Calculate cumulative distribution function of of all histograms. They
+ allow to create random number sequences
which are distributed according to the histograms. Required to generate
the "synthetic" histograms for the Bootstrap method */
-void calc_cummulants(t_UmbrellaWindow *window,int nWindows,
- t_UmbrellaOptions *opt,const char *fnhist,
- const output_env_t oenv)
+void calc_cumulatives(t_UmbrellaWindow *window,int nWindows,
+ t_UmbrellaOptions *opt,const char *fnhist)
{
int i,j,k,nbin;
double last;
char *fn=0,*buf=0;
FILE *fp=0;
-
-
+
if (opt->bs_verbose)
{
snew(fn,strlen(fnhist)+10);
snew(buf,strlen(fnhist)+10);
sprintf(fn,"%s_cumul.xvg",strncpy(buf,fnhist,strlen(fnhist)-4));
- fp=xvgropen(fn,"Cummulants of umbrella histograms","z","cummulant",
- oenv);
+ fp=xvgropen(fn,"CDFs of umbrella windows","z","CDF",opt->oenv);
}
-
+
nbin=opt->bins;
for (i=0; i<nWindows; i++)
{
window[i].cum[j][0]=0.;
for (k=1; k<=nbin; k++)
window[i].cum[j][k] = window[i].cum[j][k-1]+window[i].Histo[j][k-1];
-
- /* normalize cummulant. Ensure cum[nbin]==1 */
+
+ /* normalize CDFs. Ensure cum[nbin]==1 */
last = window[i].cum[j][nbin];
for (k=0; k<=nbin; k++)
window[i].cum[j][k] /= last;
}
}
-
- printf("Cumulants of all histograms created.\n");
+
+ printf("Cumulative distriubtion functions of all histograms created.\n");
if (opt->bs_verbose)
{
for (k=0; k<=nbin; k++)
fprintf(fp,"%g\t",window[i].cum[j][k]);
fprintf(fp,"\n");
}
- printf("Wrote cumulants to %s\n",fn);
+ printf("Wrote cumulative distribution functions to %s\n",fn);
ffclose(fp);
sfree(fn);
sfree(buf);
/* Return j such that xx[j] <= x < xx[j+1] */
-void searchCummulant(double xx[], int n, double x, int *j)
+void searchCumulative(double xx[], int n, double x, int *j)
{
int ju,jm,jl;
-
-
+
jl=-1;
ju=n;
- while (ju-jl > 1)
+ while (ju-jl > 1)
{
jm=(ju+jl) >> 1;
if (x >= xx[jm])
*j=jl;
}
-
-void create_synthetic_histo(t_UmbrellaWindow *synthWindow,
- t_UmbrellaWindow *thisWindow,
+void create_synthetic_histo(t_UmbrellaWindow *synthWindow, t_UmbrellaWindow *thisWindow,
int pullid,t_UmbrellaOptions *opt)
{
- int nsynth,N,i,nbins,r_index;
- double r;
- static gmx_bool bWarnout=0;
-
-
+ int N,i,nbins,r_index,ibin;
+ double r,tausteps=0.0,a,ap,dt,x,invsqrt2,g,y,sig=0.,z,mu=0.;
+ char errstr[1024];
+
N=thisWindow->N[pullid];
+ dt=thisWindow->dt;
nbins=thisWindow->nBin;
-
- /* nsynth = nr of data points in synthetic histo */
- if (opt->dtBootStrap==0.0)
- nsynth=N;
- else
+
+ /* tau = autocorrelation time */
+ if (opt->tauBootStrap>0.0)
+ tausteps=opt->tauBootStrap/dt;
+ else if (opt->bTauIntGiven || opt->bCalcTauInt)
{
- nsynth=(int)(thisWindow->N[pullid]*thisWindow->dt/opt->dtBootStrap+0.5);
- if (nsynth>N)
- nsynth=N;
+ /* calc tausteps from g=1+2tausteps */
+ g=thisWindow->g[pullid];
+ tausteps=(g-1)/2;
}
-
- if (!bWarnout && nsynth<10)
+ else
{
- printf("\n++++ WARNING ++++\n\tOnly %d data points per synthetic histogram!\n"
- "\tYou may want to consider option -bs-dt.\n\n",nsynth);
- bWarnout=1;
+ sprintf(errstr,
+ "When generating hypothetical trajctories from given umbrella histograms,\n"
+ "autocorrelation times (ACTs) are required. Otherwise the statistical error\n"
+ "cannot be predicted. You have 3 options:\n"
+ "1) Make g_wham estimate the ACTs (options -ac and -acsig).\n"
+ "2) Calculate the ACTs by yourself (e.g. with g_analyze) and provide them\n");
+ strcat(errstr,
+ " with option -iiact for all umbrella windows.\n"
+ "3) If all ACTs are identical and know, you can define them with -bs-tau.\n"
+ " Use option (3) only if you are sure what you're doing, you may severely\n"
+ " underestimate the error if a too small ACT is given.\n");
+ gmx_fatal(FARGS,errstr);
}
- synthWindow->N [0]=nsynth;
+ synthWindow->N [0]=N;
synthWindow->pos [0]=thisWindow->pos[pullid];
synthWindow->z [0]=thisWindow->z[pullid];
synthWindow->k [0]=thisWindow->k[pullid];
synthWindow->bContrib[0]=thisWindow->bContrib[pullid];
-
+ synthWindow->g [0]=thisWindow->g [pullid];
+ synthWindow->bsWeight[0]=thisWindow->bsWeight[pullid];
+
for (i=0;i<nbins;i++)
synthWindow->Histo[0][i]=0.;
-
- for (i=0;i<nsynth;i++)
+
+ if (opt->bsMethod==bsMethod_trajGauss)
+ {
+ sig = thisWindow->sigma [pullid];
+ mu = thisWindow->aver [pullid];
+ }
+
+ /* Genrate autocorrelated Gaussian random variable with autocorrelation time tau
+ Use the following:
+ If x and y are random numbers from N(0,1) (Gaussian with average 0 and sigma=1),
+ then
+ z = a*x + sqrt(1-a^2)*y
+ is also from N(0,1), and cov(z,x) = a. Thus, by gerenating a sequence
+ x' = a*x + sqrt(1-a^2)*y, the sequnce x(t) is from N(0,1) and has an autocorrelation
+ function
+ C(t) = exp(-t/tau) with tau=-1/ln(a)
+
+ Then, use error function to turn the Gaussian random variable into a uniformly
+ distributed one in [0,1]. Eventually, use cumulative distribution function of
+ histogram to get random variables distributed according to histogram.
+ Note: The ACT of the flat distribution and of the generated histogram is not
+ 100% exactly tau, but near tau (my test was 3.8 instead of 4).
+ */
+ a=exp(-1.0/tausteps);
+ ap=sqrt(1-a*a);
+ invsqrt2=1./sqrt(2.0);
+
+ /* init random sequence */
+ x=gmx_rng_gaussian_table(opt->rng);
+
+ if (opt->bsMethod==bsMethod_traj)
+ {
+ /* bootstrap points from the umbrella histograms */
+ for (i=0;i<N;i++)
+ {
+ y=gmx_rng_gaussian_table(opt->rng);
+ x=a*x+ap*y;
+ /* get flat distribution in [0,1] using cumulative distribution function of Gauusian
+ Note: CDF(Gaussian) = 0.5*{1+erf[x/sqrt(2)]}
+ */
+ r=0.5*(1+gmx_erf(x*invsqrt2));
+ searchCumulative(thisWindow->cum[pullid],nbins+1 ,r,&r_index);
+ synthWindow->Histo[0][r_index]+=1.;
+ }
+ }
+ else if (opt->bsMethod==bsMethod_trajGauss)
+ {
+ /* bootstrap points from a Gaussian with the same average and sigma
+ as the respective umbrella histogram. The idea was, that -given
+ limited sampling- the bootstrapped histograms are otherwise biased
+ from the limited sampling of the US histos. However, bootstrapping from
+ the Gaussian seems to yield a similar estimate. */
+ i=0;
+ while (i<N)
+ {
+ y=gmx_rng_gaussian_table(opt->rng);
+ x=a*x+ap*y;
+ z = x*sig+mu;
+ ibin=floor((z-opt->min)/opt->dz);
+ if (opt->bCycl)
+ {
+ if (ibin<0)
+ while ( (ibin+=nbins) < 0);
+ else if (ibin>=nbins)
+ while ( (ibin-=nbins) >= nbins);
+ }
+
+ if (ibin>=0 && ibin<nbins)
+ {
+ synthWindow->Histo[0][ibin]+=1.;
+ i++;
+ }
+ }
+ }
+ else
{
- r=1.0*rand()/RAND_MAX;
- searchCummulant(thisWindow->cum[pullid],nbins+1 ,r,&r_index);
- synthWindow->Histo[0][r_index]+=1.;
+ gmx_fatal(FARGS,"Unknown bsMethod (id %d). That should not happen.\n",opt->bsMethod);
}
}
-void print_histograms(const char *fnhist, t_UmbrellaWindow * window,
- int nWindows, int bs_index,t_UmbrellaOptions *opt,
- const output_env_t oenv)
+void print_histograms(const char *fnhist, t_UmbrellaWindow * window, int nWindows,
+ int bs_index,t_UmbrellaOptions *opt)
{
- char *fn;
- char *buf=0,title[256];
+ char *fn=0,*buf=0,title[256];
FILE *fp;
int bins,l,i,j;
-
-
+
if (bs_index<0)
{
fn=strdup(fnhist);
}
else
{
- snew(fn,strlen(fnhist)+6);
+ snew(fn,strlen(fnhist)+10);
snew(buf,strlen(fnhist)+1);
sprintf(fn,"%s_bs%d.xvg",strncpy(buf,fnhist,strlen(fnhist)-4),bs_index);
sprintf(title,"Umbrella histograms. Bootstrap #%d",bs_index);
}
-
- fp=xvgropen(fn,title,"z","count",oenv);
+
+ fp=xvgropen(fn,title,"z","count",opt->oenv);
bins=opt->bins;
-
+
/* Write histograms */
- for(l=0;l<bins;++l)
+ for(l=0;l<bins;++l)
{
fprintf(fp,"%e\t",(double)(l+0.5)*opt->dz+opt->min);
- for(i=0;i<nWindows;++i)
+ for(i=0;i<nWindows;++i)
{
- for(j=0;j<window[i].nPull;++j)
+ for(j=0;j<window[i].nPull;++j)
{
fprintf(fp,"%e\t",window[i].Histo[j][l]);
}
}
fprintf(fp,"\n");
}
-
+
ffclose(fp);
printf("Wrote %s\n",fn);
if (buf)
}
}
+int func_wham_is_larger(const void *a, const void *b)
+{
+ double *aa,*bb;
+ aa=(double*)a;
+ bb=(double*)b;
+ if (*aa < *bb)
+ return -1;
+ else if (*aa > *bb)
+ return 1;
+ else
+ return 0;
+}
+
+
+void setRandomBsWeights(t_UmbrellaWindow *synthwin,int nAllPull, t_UmbrellaOptions *opt)
+{
+ int i;
+ double *r;
+
+ snew(r,nAllPull);
+
+ /* generate ordered random numbers between 0 and nAllPull */
+ for (i=0; i<nAllPull-1; i++)
+ {
+ r[i] = gmx_rng_uniform_real(opt->rng) * nAllPull;
+ }
+ qsort((void *)r,nAllPull-1, sizeof(double), &func_wham_is_larger);
+ r[nAllPull-1]=1.0*nAllPull;
+
+ synthwin[0].bsWeight[0]=r[0];
+ for (i=1; i<nAllPull; i++)
+ {
+ synthwin[i].bsWeight[0]=r[i]-r[i-1];
+ }
+
+ /* avoid to have zero weight by adding a tiny value */
+ for (i=0; i<nAllPull; i++)
+ if (synthwin[i].bsWeight[0] < 1e-5)
+ synthwin[i].bsWeight[0] = 1e-5;
+
+ sfree(r);
+}
-void do_bootstrapping(const char *fnres, const char* fnprof,
- const char *fnhist, char* ylabel, double *profile,
- t_UmbrellaWindow * window, int nWindows,
- t_UmbrellaOptions *opt, const output_env_t oenv)
+void do_bootstrapping(const char *fnres, const char* fnprof, const char *fnhist,
+ char* ylabel, double *profile,
+ t_UmbrellaWindow * window, int nWindows, t_UmbrellaOptions *opt)
{
t_UmbrellaWindow * synthWindow;
double *bsProfile,*bsProfiles_av, *bsProfiles_av2,maxchange=1e20,tmp,stddev;
int iAllPull,nAllPull,*allPull_winId,*allPull_pullId;
FILE *fp;
gmx_bool bExact=FALSE;
-
-
- /* init random */
+
+ /* init random generator */
if (opt->bsSeed==-1)
- srand(time(NULL));
+ opt->rng=gmx_rng_init(gmx_rng_make_seed());
else
- srand(opt->bsSeed);
-
+ opt->rng=gmx_rng_init(opt->bsSeed);
+
snew(bsProfile, opt->bins);
snew(bsProfiles_av, opt->bins);
snew(bsProfiles_av2,opt->bins);
-
+
/* Create array of all pull groups. Note that different windows
- may have different nr of pull groups
- First: Get total nr of pull groups */
+ may have different nr of pull groups
+ First: Get total nr of pull groups */
nAllPull=0;
for (i=0;i<nWindows;i++)
nAllPull+=window[i].nPull;
iAllPull=0;
/* Setup one array of all pull groups */
for (i=0;i<nWindows;i++)
+ {
for (j=0;j<window[i].nPull;j++)
{
allPull_winId[iAllPull]=i;
allPull_pullId[iAllPull]=j;
iAllPull++;
}
-
+ }
+
/* setup stuff for synthetic windows */
snew(synthWindow,nAllPull);
for (i=0;i<nAllPull;i++)
synthWindow[i].nPull=1;
synthWindow[i].nBin=opt->bins;
snew(synthWindow[i].Histo,1);
- if (!opt->bHistBootStrap)
+ if (opt->bsMethod == bsMethod_traj || opt->bsMethod == bsMethod_trajGauss)
snew(synthWindow[i].Histo[0],opt->bins);
snew(synthWindow[i].N,1);
snew(synthWindow[i].pos,1);
snew(synthWindow[i].z,1);
snew(synthWindow[i].k,1);
snew(synthWindow[i].bContrib,1);
+ snew(synthWindow[i].g,1);
+ snew(synthWindow[i].bsWeight,1);
}
-
- if (opt->bHistBootStrap)
+
+ switch(opt->bsMethod)
{
+ case bsMethod_hist:
snew(randomArray,nAllPull);
printf("\n\nWhen computing statistical errors by bootstrapping entire histograms:\n");
please_cite(stdout,"Hub2006");
+ break;
+ case bsMethod_BayesianHist :
+ /* just copy all histogams into synthWindow array */
+ for (i=0;i<nAllPull;i++)
+ {
+ winid =allPull_winId [i];
+ pullid=allPull_pullId[i];
+ copy_pullgrp_to_synthwindow(synthWindow+i,window+winid,pullid);
+ }
+ break;
+ case bsMethod_traj:
+ case bsMethod_trajGauss:
+ calc_cumulatives(window,nWindows,opt,fnhist);
+ break;
+ default:
+ gmx_fatal(FARGS,"Unknown bootstrap method. That should not have happened.\n");
}
- else
- {
- calc_cummulants(window,nWindows,opt,fnhist,oenv);
- }
-
+
/* do bootstrapping */
- fp=xvgropen(fnprof,"Boot strap profiles","z",ylabel,oenv);
+ fp=xvgropen(fnprof,"Boot strap profiles","z",ylabel,opt->oenv);
for (ib=0;ib<opt->nBootStrap;ib++)
{
printf(" *******************************************\n"
- " ******** Start bootstrap nr %d ************\n"
- " *******************************************\n",ib+1);
-
- if (opt->bHistBootStrap)
+ " ******** Start bootstrap nr %d ************\n"
+ " *******************************************\n",ib+1);
+
+ switch(opt->bsMethod)
{
- /* only mix given histos */
- getRandomIntArray(nAllPull,opt->histBootStrapBlockLength,randomArray);
- for (i=0;i<nAllPull;i++)
- {
+ case bsMethod_hist:
+ /* bootstrap complete histograms from given histograms */
+ getRandomIntArray(nAllPull,opt->histBootStrapBlockLength,randomArray,opt->rng);
+ for (i=0;i<nAllPull;i++){
winid =allPull_winId [randomArray[i]];
pullid=allPull_pullId[randomArray[i]];
copy_pullgrp_to_synthwindow(synthWindow+i,window+winid,pullid);
}
- }
- else
- {
- /* create new histos from given histos */
+ break;
+ case bsMethod_BayesianHist:
+ /* keep histos, but assign random weights ("Bayesian bootstrap") */
+ setRandomBsWeights(synthWindow,nAllPull,opt);
+ break;
+ case bsMethod_traj:
+ case bsMethod_trajGauss:
+ /* create new histos from given histos, that is generate new hypothetical
+ trajectories */
for (i=0;i<nAllPull;i++)
{
winid=allPull_winId[i];
- pullid=allPull_pullId[i];
+ pullid=allPull_pullId[i];
create_synthetic_histo(synthWindow+i,window+winid,pullid,opt);
}
+ break;
}
-
- /* print histos in case of verbose output */
+
+ /* write histos in case of verbose output */
if (opt->bs_verbose)
- print_histograms(fnhist,synthWindow,nAllPull,ib,opt,oenv);
-
+ print_histograms(fnhist,synthWindow,nAllPull,ib,opt);
+
/* do wham */
i=0;
bExact=FALSE;
maxchange=1e20;
memcpy(bsProfile,profile,opt->bins*sizeof(double)); /* use profile as guess */
- do {
+ do
+ {
+ if ( (i%opt->stepUpdateContrib) == 0)
+ setup_acc_wham(bsProfile,synthWindow,nAllPull,opt);
if (maxchange<opt->Tolerance)
bExact=TRUE;
if (((i%opt->stepchange) == 0 || i==1) && !i==0)
i++;
} while( (maxchange=calc_z(bsProfile, synthWindow, nAllPull, opt,bExact)) > opt->Tolerance || !bExact);
printf("\tConverged in %d iterations. Final maximum change %g\n",i,maxchange);
-
+
if (opt->bLog)
prof_normalization_and_unit(bsProfile,opt);
- /* Force cyclic profile by wheighted correction */
- if (opt->cycl==enCycl_weighted)
- cyclicProfByWeightedCorr(bsProfile,synthWindow,nAllPull,opt,
- FALSE, 0,oenv);
-
+
+ /* symmetrize profile around z=0 */
+ if (opt->bSym)
+ symmetrizeProfile(bsProfile,opt);
+
/* save stuff to get average and stddev */
for (i=0;i<opt->bins;i++)
{
fprintf(fp,"&\n");
}
ffclose(fp);
-
+
/* write average and stddev */
- fp=ffopen(fnres,"w");
- fprintf(fp,"@ title \"%s\"\n","Average and stddev from bootstrapping");
- fprintf(fp,"@ xaxis label \"%s\"\n","z");
- fprintf(fp,"@ yaxis label \"%s\"\n",ylabel);
+ fp=xvgropen(fnres,"Average and stddev from bootstrapping","z",ylabel,opt->oenv);
fprintf(fp,"@TYPE xydy\n");
for (i=0;i<opt->bins;i++)
{
printf("Wrote boot strap result to %s\n",fnres);
}
-
-int whaminFileType(const char *fn)
+int whaminFileType(char *fn)
{
int len;
len=strlen(fn);
return whamin_unknown;
}
-
void read_wham_in(const char *fn,char ***filenamesRet, int *nfilesRet,
t_UmbrellaOptions *opt)
{
- char **filename,tmp[STRLEN];
- int nread,sizenow,i,block=10;
+ char **filename=0,tmp[STRLEN];
+ int nread,sizenow,i,block=1;
FILE *fp;
-#define MAXFILELEN 512
-
-
+
fp=ffopen(fn,"r");
- sizenow=block;
- snew(filename,sizenow);
- for (i=0;i<sizenow;i++)
- snew(filename[i],MAXFILELEN);
nread=0;
+ sizenow=0;
while (fscanf(fp,"%s",tmp) != EOF)
{
- if (strlen(tmp)>=MAXFILELEN)
- gmx_fatal(FARGS,"Filename too long. Only %d characters allowed\n",MAXFILELEN);
- strcpy(filename[nread],tmp);
- if (opt->verbose)
- printf("Found file %s in %s\n",filename[nread],fn);
- nread++;
+ if (strlen(tmp)>=WHAM_MAXFILELEN)
+ gmx_fatal(FARGS,"Filename too long. Only %d characters allowed\n",WHAM_MAXFILELEN);
if (nread>=sizenow)
{
sizenow+=block;
srenew(filename,sizenow);
for (i=sizenow-block;i<sizenow;i++)
- snew(filename[i],MAXFILELEN);
+ snew(filename[i],WHAM_MAXFILELEN);
}
+ strcpy(filename[nread],tmp);
+ if (opt->verbose)
+ printf("Found file %s in %s\n",filename[nread],fn);
+ nread++;
}
*filenamesRet=filename;
*nfilesRet=nread;
}
-FILE *pdo_open_file(const char *fn)
+FILE *open_pdo_pipe(const char *fn, t_UmbrellaOptions *opt,gmx_bool *bPipeOpen)
{
char Buffer[1024],gunzip[1024],*Path=0;
- FILE *fp;
-
- if (!gmx_fexist(fn))
- {
- gmx_fatal(FARGS,"File %s does not exist.\n",fn);
- }
-
+ FILE *pipe=0;
+ static gmx_bool bFirst=1;
+
/* gzipped pdo file? */
- if (strcmp(fn+strlen(fn)-3,".gz")==0)
+ if ((strcmp(fn+strlen(fn)-3,".gz")==0))
{
-#ifdef HAVE_PIPES
+ /* search gunzip executable */
if(!(Path=getenv("GMX_PATH_GZIP")))
- sprintf(gunzip,"%s","/bin/gunzip");
+ {
+ if (gmx_fexist("/bin/gunzip"))
+ sprintf(gunzip,"%s","/bin/gunzip");
+ else if (gmx_fexist("/usr/bin/gunzip"))
+ sprintf(gunzip,"%s","/usr/bin/gunzip");
+ else
+ gmx_fatal(FARGS,"Cannot find executable gunzip in /bin or /usr/bin.\n"
+ "You may want to define the path to gunzip "
+ "with the environment variable GMX_PATH_GZIP.",gunzip);
+ }
else
+ {
sprintf(gunzip,"%s/gunzip",Path);
- if (!gmx_fexist(gunzip))
- gmx_fatal(FARGS,"Cannot find executable %s. You may want to define the path to gunzip "
- "with the environment variable GMX_PATH_GZIP.",gunzip);
- sprintf(Buffer,"%s -c < %s",gunzip,fn);
- if((fp=popen(Buffer,"r"))==NULL)
- {
- gmx_fatal(FARGS,"Unable to open pipe to `%s'\n",Buffer);
- }
+ if (!gmx_fexist(gunzip))
+ gmx_fatal(FARGS,"Cannot find executable %s. Please define the path to gunzip"
+ " in the environmental varialbe GMX_PATH_GZIP.",gunzip);
+ }
+ if (bFirst)
+ {
+ printf("Using gunzig executable %s\n",gunzip);
+ bFirst=0;
+ }
+ if (!gmx_fexist(fn))
+ {
+ gmx_fatal(FARGS,"File %s does not exist.\n",fn);
+ }
+ sprintf(Buffer,"%s -c < %s",gunzip,fn);
+ if (opt->verbose)
+ printf("Executing command '%s'\n",Buffer);
+#ifdef HAVE_PIPES
+ if((pipe=popen(Buffer,"r"))==NULL)
+ {
+ gmx_fatal(FARGS,"Unable to open pipe to `%s'\n",Buffer);
+ }
#else
- gmx_fatal(FARGS,"Cannot open a compressed file on platform without pipe support");
+ gmx_fatal(FARGS,"Cannot open a compressed file on platform without pipe support");
#endif
+ *bPipeOpen=TRUE;
+ }
+ else{
+ pipe=ffopen(fn,"r");
+ *bPipeOpen=FALSE;
+ }
+
+ return pipe;
+}
+
+
+FILE *open_pdo_pipe_gmx(const char *fn)
+{
+ char *fnNoGz=0;
+ FILE *pipe;
+
+ /* gzipped pdo file? */
+ if (strcmp(fn+strlen(fn)-3,".gz")==0)
+ {
+ snew(fnNoGz,strlen(fn));
+ strncpy(fnNoGz,fn,strlen(fn)-3);
+ fnNoGz[strlen(fn)-3]='\0';
+ if (gmx_fexist(fnNoGz) && gmx_fexist(fn))
+ gmx_fatal(FARGS,"Found file %s and %s. That confuses me. Please remove one of them\n",
+ fnNoGz,fn);
+ pipe=ffopen(fnNoGz,"r");
+ sfree(fnNoGz);
}
else
- {
- if((fp=ffopen(fn,"r"))==NULL)
- {
- gmx_fatal(FARGS,"Unable to open file %s\n",fn);
- }
- }
- return fp;
+ {
+ pipe=ffopen(fn,"r");
+ }
+
+ return pipe;
}
-void
-pdo_close_file(FILE *fp)
+void pdo_close_file(FILE *fp)
{
#ifdef HAVE_PIPES
pclose(fp);
#endif
}
+
/* Reading pdo files */
void read_pdo_files(char **fn, int nfiles, t_UmbrellaHeader* header,
- t_UmbrellaWindow **window, t_UmbrellaOptions *opt)
+ t_UmbrellaWindow *window, t_UmbrellaOptions *opt)
{
- FILE * file;
- real mintmp,maxtmp;
+ FILE *file;
+ real mintmp,maxtmp,done=0.;
int i;
-
-
+ gmx_bool bPipeOpen;
+ /* char Buffer0[1000]; */
+
if(nfiles<1)
gmx_fatal(FARGS,"No files found. Hick.");
-
+
/* if min and max are not given, get min and max from the input files */
if (opt->bAuto)
{
printf("Automatic determination of boundaries from %d pdo files...\n",nfiles);
opt->min=1e20;
opt->max=-1e20;
- for(i=0;i<nfiles;++i)
+ for(i=0;i<nfiles;++i)
{
- file=pdo_open_file(fn[i]);
- printf("\rOpening %s ...",fn[i]); fflush(stdout);
+ file=open_pdo_pipe(fn[i],opt,&bPipeOpen);
+ /*fgets(Buffer0,999,file);
+ fprintf(stderr,"First line '%s'\n",Buffer0); */
+ done=100.0*(i+1)/nfiles;
+ printf("\rOpening %s ... [%2.0f%%]",fn[i],done); fflush(stdout);
if (opt->verbose)
printf("\n");
read_pdo_header(file,header,opt);
opt->max=maxtmp;
if (mintmp<opt->min)
opt->min=mintmp;
- pdo_close_file(file);
+ if (bPipeOpen)
+ pdo_close_file(file);
+ else
+ ffclose(file);
}
printf("\n");
printf("\nDetermined boundaries to %f and %f\n\n",opt->min,opt->max);
}
/* store stepsize in profile */
opt->dz=(opt->max-opt->min)/opt->bins;
-
- snew(*window,nfiles);
-
+
/* Having min and max, we read in all files */
/* Loop over all files */
- for(i=0;i<nfiles;++i)
+ for(i=0;i<nfiles;++i)
{
- printf("\rOpening %s ...",fn[i]); fflush(stdout);
+ done=100.0*(i+1)/nfiles;
+ printf("\rOpening %s ... [%2.0f%%]",fn[i],done); fflush(stdout);
if (opt->verbose)
printf("\n");
- file=pdo_open_file(fn[i]);
- /* read in the headers */
+ file=open_pdo_pipe(fn[i],opt,&bPipeOpen);
read_pdo_header(file,header,opt);
/* load data into window */
- read_pdo_data(file,header,i,*window,opt,FALSE,NULL,NULL);
- pdo_close_file(file);
+ read_pdo_data(file,header,i,window,opt,FALSE,NULL,NULL);
+ if ((window+i)->Ntot[0] == 0.0)
+ fprintf(stderr,"\nWARNING, no data points read from file %s (check -b option)\n", fn[i]);
+ if (bPipeOpen)
+ pdo_close_file(file);
+ else
+ ffclose(file);
}
printf("\n");
+ for(i=0;i<nfiles;++i)
+ sfree(fn[i]);
+ sfree(fn);
}
-
#define int2YN(a) (((a)==0)?("N"):("Y"))
-void read_tpr_header(const char *fn,t_UmbrellaHeader* header,
- t_UmbrellaOptions *opt)
+void read_tpr_header(const char *fn,t_UmbrellaHeader* header,t_UmbrellaOptions *opt)
{
t_inputrec ir;
- int i,ngrp,d;
+ int i,ngrp,d;
t_state state;
static int first=1;
-
-
+
/* printf("Reading %s \n",fn); */
read_tpx_state(fn,&ir,&state,NULL,NULL);
-
+
if (ir.ePull != epullUMBRELLA)
- gmx_fatal(FARGS,"This is not a tpr of an umbrella simulation. Found ir.ePull = %s\n",
- epull_names[ir.ePull]);
-
+ gmx_fatal(FARGS,"This is not a tpr of an umbrella simulation. Found pull type \"%s\" "
+ " (ir.ePull = %d)\n", epull_names[ir.ePull],ir.ePull);
+
/* nr of pull groups */
ngrp=ir.pull->ngrp;
if (ngrp < 1)
gmx_fatal(FARGS,"This is not a tpr of umbrella simulation. Found only %d pull groups\n",ngrp);
-
+
header->npullgrps=ir.pull->ngrp;
header->pull_geometry=ir.pull->eGeom;
copy_ivec(ir.pull->dim,header->pull_dim);
header->pull_ndim=header->pull_dim[0]+header->pull_dim[1]+header->pull_dim[2];
if (header->pull_geometry==epullgPOS && header->pull_ndim>1)
+ {
gmx_fatal(FARGS,"Found pull geometry 'position' and more than 1 pull dimension (%d).\n"
- "Hence, the pull potential does not correspond to a one-dimensional umbrella potential.\n"
- "If you have some special umbrella setup you may want to write your own pdo files\n"
- "and feed them into g_wham. Check g_wham -h !\n",header->pull_ndim);
+ "Hence, the pull potential does not correspond to a one-dimensional umbrella potential.\n"
+ "If you have some special umbrella setup you may want to write your own pdo files\n"
+ "and feed them into g_wham. Check g_wham -h !\n",header->pull_ndim);
+ }
snew(header->k,ngrp);
snew(header->init_dist,ngrp);
snew(header->umbInitDist,ngrp);
+
+ /* only z-direction with epullgCYL? */
+ if (header->pull_geometry == epullgCYL)
+ {
+ if (header->pull_dim[XX] || header->pull_dim[YY] || (!header->pull_dim[ZZ]))
+ gmx_fatal(FARGS,"With pull geometry 'cylinder', expected pulling in Z direction only.\n"
+ "However, found dimensions [%s %s %s]\n",
+ int2YN(header->pull_dim[XX]),int2YN(header->pull_dim[YY]),
+ int2YN(header->pull_dim[ZZ]));
+ }
for (i=0;i<ngrp;i++)
{
header->k[i]=ir.pull->grp[i+1].k;
if (header->k[i]==0.0)
gmx_fatal(FARGS,"Pull group %d has force constant of of 0.0 in %s.\n"
- "That doesn't seem to be an Umbrella tpr.\n",
- i,fn);
+ "That doesn't seem to be an Umbrella tpr.\n",
+ i,fn);
copy_rvec(ir.pull->grp[i+1].init,header->init_dist[i]);
- header->Flipped[i]=opt->bFlipProf;
-
+
/* initial distance to reference */
switch(header->pull_geometry)
{
if (header->pull_dim[d])
header->umbInitDist[i]=header->init_dist[i][d];
break;
+ case epullgCYL:
+ /* umbrella distance stored in init_dist[i][0] for geometry cylinder (not in ...[i][ZZ]) */
case epullgDIST:
+ case epullgDIR:
+ case epullgDIRPBC:
header->umbInitDist[i]=header->init_dist[i][0];
break;
default:
gmx_fatal(FARGS,"Pull geometry %s not supported\n",epullg_names[header->pull_geometry]);
}
}
-
+
if (opt->verbose || first)
{
printf("File %s, %d groups, geometry \"%s\", dimensions [%s %s %s], (%d dimensions)\n",
- fn,header->npullgrps,epullg_names[header->pull_geometry],
- int2YN(header->pull_dim[0]),int2YN(header->pull_dim[1]),int2YN(header->pull_dim[2]),
- header->pull_ndim);
+ fn,header->npullgrps,epullg_names[header->pull_geometry],
+ int2YN(header->pull_dim[0]),int2YN(header->pull_dim[1]),int2YN(header->pull_dim[2]),
+ header->pull_ndim);
for (i=0;i<ngrp;i++)
- printf("\tgrp %d) k = %.3f inittial distance = %g\n",i,header->k[i],header->umbInitDist[i]);
+ printf("\tgrp %d) k = %-5g position = %g\n",i,header->k[i],header->umbInitDist[i]);
}
+ if (!opt->verbose && first)
+ printf("\tUse option -v to see this output for all input tpr files\n");
+
first=0;
}
{
int i;
double r2=0.;
-
-
for (i=0;i<ndim;i++)
r2+=sqr(dx[i][line]);
-
return sqrt(r2);
}
-
-void read_pull_xf(const char *fn, const char *fntpr,
- t_UmbrellaHeader * header, t_UmbrellaWindow * window,
- t_UmbrellaOptions *opt, gmx_bool bGetMinMax,real *mintmp,
- real *maxtmp)
+void read_pull_xf(const char *fn, const char *fntpr, t_UmbrellaHeader * header,
+ t_UmbrellaWindow * window,
+ t_UmbrellaOptions *opt,
+ gmx_bool bGetMinMax,real *mintmp,real *maxtmp)
{
- double **y,pos=0.,t,force,time0=0.,dt;
- int ny,nt,bins,ibin,i,g,dstep=1,nColPerGrp,nColRef,nColExpect;
- real min,max,minfound,maxfound;
+ double **y=0,pos=0.,t,force,time0=0.,dt;
+ int ny,nt,bins,ibin,i,g,dstep=1,nColPerGrp,nColRefOnce,nColRefEachGrp,nColExpect,ntot;
+ real min,max,minfound=1e20,maxfound=-1e20;
gmx_bool dt_ok,timeok,bHaveForce;
const char *quantity;
+ const int blocklen=4096;
+ int *lennow=0;
+
+ /*
+ in force output pullf.xvg:
+ No reference, one column per pull group
+ in position output pullx.xvg (not cylinder)
+ ndim reference, ndim columns per pull group
+ in position output pullx.xvg (in geometry cylinder):
+ ndim*2 columns per pull group (ndim for ref, ndim for group)
+ */
- minfound=1e20;
- maxfound=-1e20;
-
- /*
- in force output pullf.xvg: No reference, one column per pull group
- in position output pullx.xvg: ndim reference, ndim columns per pull group
- */
nColPerGrp = opt->bPullx ? header->pull_ndim : 1;
- nColRef = opt->bPullx ? header->pull_ndim : 0;
quantity = opt->bPullx ? "position" : "force";
- nColExpect = 1 + nColRef + header->npullgrps*nColPerGrp;
+
+ if (opt->bPullx)
+ {
+ if (header->pull_geometry == epullgCYL)
+ {
+ /* Geometry cylinder -> reference group before each pull group */
+ nColRefEachGrp=header->pull_ndim;
+ nColRefOnce=0;
+ }
+ else
+ {
+ /* Geometry NOT cylinder -> reference group only once after time column */
+ nColRefEachGrp=0;
+ nColRefOnce=header->pull_ndim;
+ }
+ }
+ else /* read forces, no reference groups */
+ {
+ nColRefEachGrp=0;
+ nColRefOnce=0;
+ }
+ nColExpect = 1 + nColRefOnce + header->npullgrps*(nColRefEachGrp+nColPerGrp);
bHaveForce = opt->bPullf;
-
+
+ /* With geometry "distance" or "distance_periodic", only force reading is supported so far.
+ That avoids the somewhat tedious extraction of the right columns from the pullx files
+ to compute the distances projection on the vector. Sorry for the laziness. */
+ if ( (header->pull_geometry==epullgDIR || header->pull_geometry==epullgDIRPBC)
+ && opt->bPullx)
+ {
+ gmx_fatal(FARGS,"With pull geometries \"direction\" and \"direction_periodic\", only pull force "
+ "reading \n(option -if) is supported at present, "
+ "not pull position reading (options -ix).\nMake sure mdrun writes the pull "
+ "forces (pullf.xvg files)\nand provide them to g_wham with option -if.",
+ epullg_names[header->pull_geometry]);
+ }
+
nt=read_xvg(fn,&y,&ny);
/* Check consistency */
if (nt<1)
+ {
gmx_fatal(FARGS,"Empty pull %s file %s\n",quantity,fn);
+ }
if (ny != nColExpect)
+ {
gmx_fatal(FARGS,"Found %d pull groups in %s,\n but %d data columns in %s (expected %d)\n",
- header->npullgrps,fntpr,ny-1,fn,nColExpect-1);
-
+ header->npullgrps,fntpr,ny-1,fn,nColExpect-1);
+ }
+
if (opt->verbose)
printf("Found %d times and %d %s sets %s\n",nt,(ny-1)/nColPerGrp,quantity,fn);
-
+
if (!bGetMinMax)
{
bins=opt->bins;
min=opt->min;
max=opt->max;
if (nt>1)
+ {
window->dt=y[0][1]-y[0][0];
- else if (opt->nBootStrap && opt->dtBootStrap!=0.0)
+ }
+ else if (opt->nBootStrap && opt->tauBootStrap!=0.0)
+ {
fprintf(stderr,"\n *** WARNING, Could not determine time step in %s\n",fn);
-
+ }
+
/* Need to alocate memory and set up structure */
window->nPull=header->npullgrps;
window->nBin=bins;
-
+
snew(window->Histo,window->nPull);
snew(window->z,window->nPull);
snew(window->k,window->nPull);
snew(window->pos,window->nPull);
- snew(window->Flipped,window->nPull);
snew(window->N, window->nPull);
snew(window->Ntot, window->nPull);
+ snew(window->g, window->nPull);
+ snew(window->bsWeight, window->nPull);
+ window->bContrib=0;
- for(g=0;g<window->nPull;++g)
+ if (opt->bCalcTauInt)
+ snew(window->ztime,window->nPull);
+ else
+ window->ztime=NULL;
+ snew(lennow,window->nPull);
+
+ for(g=0;g<window->nPull;++g)
{
window->z[g]=1;
+ window->bsWeight[g]=1.;
snew(window->Histo[g],bins);
window->k[g]=header->k[g];
- window->Flipped[g]=header->Flipped[g];
window->N[g]=0;
window->Ntot[g]=0;
+ window->g[g]=1.;
window->pos[g]=header->umbInitDist[g];
+ if (opt->bCalcTauInt)
+ window->ztime[g]=NULL;
}
+
}
else
- {
- /* only determine min and max */
+ { /* only determine min and max */
minfound=1e20;
maxfound=-1e20;
min=max=bins=0; /* Get rid of warnings */
}
- if(header->Flipped[0])
- gmx_fatal(FARGS,"Sorry, flipping not supported for gmx4 output\n");
-
for (i=0;i<nt;i++)
{
/* Do you want that time frame? */
- t=1.0/1000*((int)(0.5+y[0][i]*1000)); /* round time to fs */
-
+ t=1.0/1000*( (int) ((y[0][i]*1000) + 0.5)); /* round time to fs */
+
/* get time step of pdo file and get dstep from opt->dt */
if (i==0)
+ {
time0=t;
+ }
else if (i==1)
{
dt=t-time0;
if (!bGetMinMax)
window->dt=dt*dstep;
}
-
+
dt_ok=(i%dstep == 0);
timeok=(dt_ok && t >= opt->tmin && t <= opt->tmax);
/*if (opt->verbose)
- printf(" time = %f, (tmin,tmax)=(%e,%e), dt_ok=%d timeok=%d\n",
- t,opt->tmin, opt->tmax, dt_ok,timeok); */
-
+ printf(" time = %f, (tmin,tmax)=(%e,%e), dt_ok=%d timeok=%d\n",
+ t,opt->tmin, opt->tmax, dt_ok,timeok); */
+
if (timeok)
{
- for(g=0;g<header->npullgrps;++g)
+ for(g=0;g<header->npullgrps;++g)
{
if (bHaveForce)
{
switch (header->pull_geometry)
{
case epullgDIST:
- /* y has 1 time column y[0] and nColPerGrps columns per pull group;
- Distance to reference: */
- pos=dist_ndim(y+1+nColRef+g*nColPerGrp,header->pull_ndim,i);
+ /* y has 1 time column y[0] and nColPerGrps columns per pull group;
+ Distance to reference: */
+ /* pos=dist_ndim(y+1+nColRef+g*nColPerGrp,header->pull_ndim,i); gmx 4.0 */
+ pos=dist_ndim(y + 1 + nColRefOnce + g*nColPerGrp,header->pull_ndim,i);
break;
case epullgPOS:
- /* with geometry==position, we have always one column per group;
- Distance to reference: */
- pos=y[1+nColRef+g][i];
+ case epullgCYL:
+ /* with geometry==position, we have the reference once (nColRefOnce==ndim), but
+ no extra reference group columns before each group (nColRefEachGrp==0)
+ with geometry==cylinder, we have no initial ref group column (nColRefOnce==0),
+ but ndim ref group colums before every group (nColRefEachGrp==ndim)
+ Distance to reference: */
+ pos=y[1 + nColRefOnce + g*(nColRefEachGrp+nColPerGrp)][i];
break;
default:
gmx_fatal(FARGS,"Bad error, this error should have been catched before. Ups.\n");
}
}
-
+
/* printf("grp %d dpos %f poseq %f pos %f \n",g,dpos,poseq,pos); */
if (bGetMinMax)
{
}
else
{
+ if (opt->bCalcTauInt && !bGetMinMax)
+ {
+ /* save time series for autocorrelation analysis */
+ ntot=window->Ntot[g];
+ /* printf("i %d, ntot %d, lennow[g] = %d\n",i,ntot,lennow[g]); */
+ if (ntot>=lennow[g])
+ {
+ lennow[g]+=blocklen;
+ srenew(window->ztime[g],lennow[g]);
+ }
+ window->ztime[g][ntot]=pos;
+ }
+
ibin=(int) floor((pos-min)/(max-min)*bins);
- if (opt->cycl==enCycl_yes)
+ if (opt->bCycl)
{
if (ibin<0)
while ( (ibin+=bins) < 0);
else if (ibin>=bins)
while ( (ibin-=bins) >= bins);
- }
- if(ibin >= 0 && ibin < bins)
+ }
+ if(ibin >= 0 && ibin < bins)
{
window->Histo[g][ibin]+=1.;
window->N[g]++;
break;
}
}
-
+
if (bGetMinMax)
{
*mintmp=minfound;
*maxtmp=maxfound;
}
+ sfree(lennow);
+ for (i=0;i<ny;i++)
+ sfree(y[i]);
}
-
-void read_tpr_pullxf_files(char **fnTprs,char **fnPull,
- int nfiles, t_UmbrellaHeader* header,
- t_UmbrellaWindow **window, t_UmbrellaOptions *opt)
+void read_tpr_pullxf_files(char **fnTprs,char **fnPull,int nfiles,
+ t_UmbrellaHeader* header,
+ t_UmbrellaWindow *window, t_UmbrellaOptions *opt)
{
int i;
real mintmp,maxtmp;
-
-
- printf("Reading %d tpr and pullf files\n",nfiles);
-
+
+ printf("Reading %d tpr and pullf files\n",nfiles/2);
+
/* min and max not given? */
if (opt->bAuto)
{
read_tpr_header(fnTprs[i],header,opt);
if (whaminFileType(fnPull[i]) != whamin_pullxf)
gmx_fatal(FARGS,"Expected the %d'th file in input file to be a xvg (pullx/pullf) file\n",i);
- read_pull_xf(fnPull[i],fnTprs[i],header,NULL,opt,TRUE,&mintmp,&maxtmp);
+ read_pull_xf(fnPull[i],fnTprs[i],header,NULL,opt,TRUE,&mintmp,&maxtmp);
if (maxtmp>opt->max)
opt->max=maxtmp;
if (mintmp<opt->min)
opt->min=mintmp;
}
printf("\nDetermined boundaries to %f and %f\n\n",opt->min,opt->max);
- if (opt->bBoundsOnly){
+ if (opt->bBoundsOnly)
+ {
printf("Found option -boundsonly, now exiting.\n");
exit (0);
}
/* store stepsize in profile */
opt->dz=(opt->max-opt->min)/opt->bins;
- snew(*window,nfiles);
for (i=0;i<nfiles; i++)
{
if (whaminFileType(fnTprs[i]) != whamin_tpr)
read_tpr_header(fnTprs[i],header,opt);
if (whaminFileType(fnPull[i]) != whamin_pullxf)
gmx_fatal(FARGS,"Expected the %d'th file in input file to be a xvg (pullx/pullf) file\n",i);
- read_pull_xf(fnPull[i],fnTprs[i],header,*window+i,opt,FALSE,NULL,NULL);
+ read_pull_xf(fnPull[i],fnTprs[i],header,window+i,opt,FALSE,NULL,NULL);
+ if (window[i].Ntot[0] == 0.0)
+ fprintf(stderr,"\nWARNING, no data points read from file %s (check -b option)\n", fnPull[i]);
+ }
+
+ for (i=0;i<nfiles; i++)
+ {
+ sfree(fnTprs[i]);
+ sfree(fnPull[i]);
+ }
+ sfree(fnTprs);
+ sfree(fnPull);
+}
+
+/* Note: Here we consider tau[int] := int_0^inf ACF(t) as the integrated autocorrelation time.
+ The factor `g := 1 + 2*tau[int]` subsequently enters the uncertainty.
+*/
+void readIntegratedAutocorrelationTimes(t_UmbrellaWindow *window,int nwins,t_UmbrellaOptions *opt,
+ const char* fn)
+{
+ int nlines,ny,i,ig;
+ double **iact;
+
+ printf("Readging Integrated autocorrelation times from %s ...\n",fn);
+ nlines=read_xvg(fn,&iact,&ny);
+ if (nlines!=nwins)
+ gmx_fatal(FARGS,"Found %d lines with integrated autocorrelation times in %s.\nExpected %d",
+ nlines,fn,nwins);
+ for (i=0;i<nlines;i++){
+ if (window[i].nPull != ny)
+ gmx_fatal(FARGS,"You are providing autocorrelation times with option -iiact and the\n"
+ "number of pull groups is different in different simulations. That is not\n"
+ "supported yet. Sorry.\n");
+ for (ig=0;ig<window[i].nPull;ig++){
+ /* compare Kumar et al, J Comp Chem 13, 1011-1021 (1992) */
+ window[i].g[ig]=1+2*iact[ig][i]/window[i].dt;
+
+ if (iact[ig][i] <= 0.0)
+ fprintf(stderr,"\nWARNING, IACT = %f (window %d, group %d)\n", iact[ig][i],i,ig);
+ }
}
}
+/* Smooth autocorreltion times along the reaction coordinate. This is useful
+ if the ACT is subject to high uncertainty in case if limited sampling. Note
+ that -in case of limited sampling- the ACT may be severely underestimated.
+ Note: the g=1+2tau are overwritten.
+ if opt->bAllowReduceIact==FALSE, the ACTs are never reduced, only increased
+ by the smoothing
+*/
+void smoothIact(t_UmbrellaWindow *window,int nwins,t_UmbrellaOptions *opt)
+{
+ int i,ig,j,jg;
+ double pos,dpos2,siglim,siglim2,gaufact,invtwosig2,w,weight,tausm;
+
+ /* only evaluate within +- 3sigma of the Gausian */
+ siglim=3.0*opt->sigSmoothIact;
+ siglim2=dsqr(siglim);
+ /* pre-factor of Gaussian */
+ gaufact=1.0/(sqrt(2*M_PI)*opt->sigSmoothIact);
+ invtwosig2=0.5/dsqr(opt->sigSmoothIact);
+
+ for (i=0;i<nwins;i++)
+ {
+ snew(window[i].tausmooth,window[i].nPull);
+ for (ig=0;ig<window[i].nPull;ig++)
+ {
+ tausm=0.;
+ weight=0;
+ pos=window[i].pos[ig];
+ for (j=0;j<nwins;j++)
+ {
+ for (jg=0;jg<window[j].nPull;jg++)
+ {
+ dpos2=dsqr(window[j].pos[jg]-pos);
+ if (dpos2<siglim2){
+ w=gaufact*exp(-dpos2*invtwosig2);
+ weight+=w;
+ tausm+=w*window[j].tau[jg];
+ /*printf("Weight %g dpos2=%g pos=%g gaufact=%g invtwosig2=%g\n",
+ w,dpos2,pos,gaufact,invtwosig2); */
+ }
+ }
+ }
+ tausm/=weight;
+ if (opt->bAllowReduceIact || tausm>window[i].tau[ig])
+ window[i].tausmooth[ig]=tausm;
+ else
+ window[i].tausmooth[ig]=window[i].tau[ig];
+ window[i].g[ig] = 1+2*tausm/window[i].dt;
+ }
+ }
+}
+
+/* try to compute the autocorrelation time for each umbrealla window */
+#define WHAM_AC_ZERO_LIMIT 0.05
+void calcIntegratedAutocorrelationTimes(t_UmbrellaWindow *window,int nwins,
+ t_UmbrellaOptions *opt, const char *fn)
+{
+ int i,ig,ncorr,ntot,j,k,*count,restart;
+ real *corr,c0,dt,timemax,tmp;
+ real *ztime,av,tausteps;
+ FILE *fp,*fpcorr=0;
+
+ if (opt->verbose)
+ fpcorr=xvgropen("hist_autocorr.xvg","Autocorrelation functions of umbrella windows",
+ "time [ps]","autocorrelation function",opt->oenv);
+
+ printf("\n");
+ for (i=0;i<nwins;i++)
+ {
+ printf("\rEstimating integrated autocorreltion times ... [%2.0f%%] ...",100.*(i+1)/nwins);
+ fflush(stdout);
+ ntot=window[i].Ntot[0];
+
+ /* using half the maximum time as length of autocorrelation function */
+ ncorr=ntot/2;
+ if (ntot<10)
+ gmx_fatal(FARGS,"Tryig to estimtate autocorrelation time from only %d"
+ " points. Provide more pull data!",ntot);
+ snew(corr,ncorr);
+ /* snew(corrSq,ncorr); */
+ snew(count,ncorr);
+ dt=window[i].dt;
+ timemax=dt*ncorr;
+ snew(window[i].tau,window[i].nPull);
+ restart=(int)(opt->acTrestart/dt+0.5);
+ if (restart==0)
+ restart=1;
+
+ for (ig=0;ig<window[i].nPull;ig++)
+ {
+ if (ntot != window[i].Ntot[ig])
+ gmx_fatal(FARGS,"Encountered different nr of frames in different pull groups.\n"
+ "That should not happen. (%d and %d)\n", ntot,window[i].Ntot[ig]);
+ ztime=window[i].ztime[ig];
+
+ /* calc autocorrelation function C(t) = < [z(tau)-<z>]*[z(tau+t)-<z>]> */
+ for(j=0, av=0; (j<ntot); j++)
+ av+=ztime[j];
+ av/=ntot;
+ for(k=0; (k<ncorr); k++)
+ {
+ corr[k]=0.;
+ count[k]=0;
+ }
+ for(j=0; (j<ntot); j+=restart)
+ for(k=0; (k<ncorr) && (j+k < ntot); k++)
+ {
+ tmp=(ztime[j]-av)*(ztime[j+k]-av);
+ corr [k] += tmp;
+ /* corrSq[k] += tmp*tmp; */
+ count[k]++;
+ }
+ /* divide by nr of frames for each time displacement */
+ for(k=0; (k<ncorr); k++)
+ {
+ /* count probably = (ncorr-k+(restart-1))/restart; */
+ corr[k] = corr[k]/count[k];
+ /* variance of autocorrelation function */
+ /* corrSq[k]=corrSq[k]/count[k]; */
+ }
+ /* normalize such that corr[0] == 0 */
+ c0=1./corr[0];
+ for(k=0; (k<ncorr); k++)
+ {
+ corr[k]*=c0;
+ /* corrSq[k]*=c0*c0; */
+ }
+
+ /* write ACFs in verbose mode */
+ if (fpcorr)
+ {
+ for(k=0; (k<ncorr); k++)
+ fprintf(fpcorr,"%g %g\n",k*dt,corr[k]);
+ fprintf(fpcorr,"&\n");
+ }
+
+ /* esimate integrated correlation time, fitting is too unstable */
+ tausteps = 0.5*corr[0];
+ /* consider corr below WHAM_AC_ZERO_LIMIT as noise */
+ for(j=1; (j<ncorr) && (corr[j]>WHAM_AC_ZERO_LIMIT); j++)
+ tausteps += corr[j];
+
+ /* g = 1+2*tau, see. Ferrenberg/Swendsen, PRL 63:1195 (1989) or
+ Kumar et al, eq. 28 ff. */
+ window[i].tau[ig] = tausteps*dt;
+ window[i].g[ig] = 1+2*tausteps;
+ /* printf("win %d, group %d, estimated correlation time = %g ps\n",i,ig,window[i].tau[ig]); */
+ } /* ig loop */
+ sfree(corr);
+ sfree(count);
+ }
+ printf(" done\n");
+ if (fpcorr)
+ ffclose(fpcorr);
+
+ /* plot IACT along reaction coordinate */
+ fp=xvgropen(fn,"Integrated autocorrelation times","z","IACT [ps]",opt->oenv);
+ fprintf(fp,"@ s0 symbol 1\n@ s0 symbol size 0.5\n@ s0 line linestyle 0\n");
+ fprintf(fp,"# WIN tau(gr1) tau(gr2) ...\n");
+ for (i=0;i<nwins;i++)
+ {
+ fprintf(fp,"# %3d ",i);
+ for (ig=0;ig<window[i].nPull;ig++)
+ fprintf(fp," %11g",window[i].tau[ig]);
+ fprintf(fp,"\n");
+ }
+ for (i=0;i<nwins;i++)
+ for (ig=0;ig<window[i].nPull;ig++)
+ fprintf(fp,"%8g %8g\n",window[i].pos[ig],window[i].tau[ig]);
+ if (opt->sigSmoothIact > 0.0)
+ {
+ printf("Smoothing autocorrelation times along reaction coordinate with Gaussian of sig = %g\n",
+ opt->sigSmoothIact);
+ /* smooth IACT along reaction coordinate and overwrite g=1+2tau */
+ smoothIact(window,nwins,opt);
+ fprintf(fp,"&\n@ s1 symbol 1\n@ s1 symbol size 0.5\n@ s1 line linestyle 0\n");
+ fprintf(fp,"@ s1 symbol color 2\n");
+ for (i=0;i<nwins;i++)
+ for (ig=0;ig<window[i].nPull;ig++)
+ fprintf(fp,"%8g %8g\n",window[i].pos[ig],window[i].tausmooth[ig]);
+ }
+ ffclose(fp);
+ printf("Wrote %s\n",fn);
+}
+
+/* compute average and sigma of each umbrella window */
+void averageSigma(t_UmbrellaWindow *window,int nwins,t_UmbrellaOptions *opt)
+{
+ int i,ig,ntot,k;
+ real av,sum2,sig,diff,*ztime,nSamplesIndep;
+
+ for (i=0;i<nwins;i++)
+ {
+ snew(window[i].aver, window[i].nPull);
+ snew(window[i].sigma,window[i].nPull);
+
+ ntot=window[i].Ntot[0];
+ for (ig=0;ig<window[i].nPull;ig++)
+ {
+ ztime=window[i].ztime[ig];
+ for (k=0, av=0.; k<ntot; k++)
+ av+=ztime[k];
+ av/=ntot;
+ for (k=0, sum2=0.; k<ntot; k++)
+ {
+ diff=ztime[k]-av;
+ sum2+=diff*diff;
+ }
+ sig=sqrt(sum2/ntot);
+ window[i].aver[ig]=av;
+
+ /* Note: This estimate for sigma is biased from the limited sampling.
+ Correct sigma by n/(n-1) where n = number of independent
+ samples. Only possible if IACT is known.
+ */
+ if (window[i].tau)
+ {
+ nSamplesIndep=window[i].N[ig]/(window[i].tau[ig]/window[i].dt);
+ window[i].sigma[ig]=sig * nSamplesIndep/(nSamplesIndep-1);
+ }
+ else
+ window[i].sigma[ig]=sig;
+ printf("win %d, aver = %f sig = %f\n",i,av,window[i].sigma[ig]);
+ }
+ }
+}
+
+
+/* Use histograms to compute average force on pull group.
+ In addition, compute the sigma of the histogram.
+*/
+void computeAverageForce(t_UmbrellaWindow *window,int nWindows,t_UmbrellaOptions *opt)
+{
+ int i,j,bins=opt->bins,k;
+ double dz,min=opt->min,max=opt->max,displAv,displAv2,temp,distance,ztot,ztot_half,w,weight;
+ double posmirrored;
+
+ dz=(max-min)/bins;
+ ztot=opt->max-min;
+ ztot_half=ztot/2;
+
+ /* Compute average displacement from histograms */
+ for(j=0;j<nWindows;++j)
+ {
+ snew(window[j].forceAv,window[j].nPull);
+ for(k=0;k<window[j].nPull;++k)
+ {
+ displAv = 0.0;
+ displAv2 = 0.0;
+ weight = 0.0;
+ for(i=0;i<opt->bins;++i)
+ {
+ temp=(1.0*i+0.5)*dz+min;
+ distance = temp - window[j].pos[k];
+ if (opt->bCycl)
+ { /* in cyclic wham: */
+ if (distance > ztot_half) /* |distance| < ztot_half */
+ distance-=ztot;
+ else if (distance < -ztot_half)
+ distance+=ztot;
+ }
+ w=window[j].Histo[k][i]/window[j].g[k];
+ displAv += w*distance;
+ displAv2 += w*sqr(distance);
+ weight+=w;
+ /* Are we near min or max? We are getting wron forces from the histgrams since
+ the histigrams are zero outside [min,max). Therefore, assume that the position
+ on the other side of the histomgram center is equally likely. */
+ if (!opt->bCycl)
+ {
+ posmirrored=window[j].pos[k]-distance;
+ if (posmirrored>=max || posmirrored<min)
+ {
+ displAv += -w*distance;
+ displAv2 += w*sqr(-distance);
+ weight+=w;
+ }
+ }
+ }
+ displAv /= weight;
+ displAv2 /= weight;
+
+ /* average force from average displacement */
+ window[j].forceAv[k] = displAv*window[j].k[k];
+ /* sigma from average square displacement */
+ /* window[j].sigma [k] = sqrt(displAv2); */
+ /* printf("Win %d, sigma = %f\n",j,sqrt(displAv2)); */
+ }
+ }
+}
+
+/* Check if the complete reaction coordinate is covered by the histograms */
+void checkReactionCoordinateCovered(t_UmbrellaWindow *window,int nwins,
+ t_UmbrellaOptions *opt)
+{
+ int i,ig,j,bins=opt->bins,bBoundary;
+ real avcount=0,z,relcount,*count;
+ snew(count,opt->bins);
+
+ for(j=0;j<opt->bins;++j)
+ {
+ for (i=0;i<nwins;i++){
+ for (ig=0;ig<window[i].nPull;ig++)
+ count[j]+=window[i].Histo[ig][j];
+ }
+ avcount+=1.0*count[j];
+ }
+ avcount/=bins;
+ for(j=0;j<bins;++j)
+ {
+ relcount=count[j]/avcount;
+ z=(j+0.5)*opt->dz+opt->min;
+ bBoundary=( j<bins/20 || (bins-j)>bins/20 );
+ /* check for bins with no data */
+ if (count[j] == 0)
+ fprintf(stderr, "\nWARNING, no data point in bin %d (z=%g) !\n"
+ "You may not get a reasonable profile. Check your histograms!\n",j,z);
+ /* and check for poor sampling */
+ else if (relcount<0.005 && !bBoundary)
+ fprintf(stderr, "Warning, poor sampling bin %d (z=%g). Check your histograms!\n",j,z);
+ }
+ sfree(count);
+}
+
+
+void guessPotByIntegration(t_UmbrellaWindow *window,int nWindows,t_UmbrellaOptions *opt,
+ char *fn)
+{
+ int i,j,ig,bins=opt->bins,nHist,winmin,groupmin;
+ double dz,min=opt->min,*pot,pos,hispos,dist,diff,fAv,distmin,*f;
+ FILE *fp;
+
+ dz=(opt->max-min)/bins;
+
+ printf("Getting initial potential by integration.\n");
+
+ /* Compute average displacement from histograms */
+ computeAverageForce(window,nWindows,opt);
+
+ /* Get force for each bin from all histograms in this bin, or, alternatively,
+ if no histograms are inside this bin, from the closest histogram */
+ snew(pot,bins);
+ snew(f,bins);
+ for(j=0;j<opt->bins;++j)
+ {
+ pos=(1.0*j+0.5)*dz+min;
+ nHist=0;
+ fAv=0.;
+ distmin=1e20;
+ groupmin=winmin=0;
+ for (i=0;i<nWindows;i++)
+ {
+ for (ig=0;ig<window[i].nPull;ig++)
+ {
+ hispos=window[i].pos[ig];
+ dist=fabs(hispos-pos);
+ /* average force within bin */
+ if (dist < dz/2)
+ {
+ nHist++;
+ fAv+=window[i].forceAv[ig];
+ }
+ /* at the same time, rememer closest histogram */
+ if (dist<distmin){
+ winmin=i;
+ groupmin=ig;
+ distmin=dist;
+ }
+ }
+ }
+ /* if no histogram found in this bin, use closest histogram */
+ if (nHist>0)
+ fAv=fAv/nHist;
+ else{
+ fAv=window[winmin].forceAv[groupmin];
+ }
+ f[j]=fAv;
+ }
+ for(j=1;j<opt->bins;++j)
+ pot[j] = pot[j-1] - 0.5*dz*(f[j-1]+f[j]);
+
+ /* cyclic wham: linearly correct possible offset */
+ if (opt->bCycl)
+ {
+ diff=(pot[bins-1]-pot[0])/(bins-1);
+ for(j=1;j<opt->bins;++j)
+ pot[j]-=j*diff;
+ }
+ if (opt->verbose)
+ {
+ fp=xvgropen("pmfintegrated.xvg","PMF from force integration","z","PMF [kJ/mol]",opt->oenv);
+ for(j=0;j<opt->bins;++j)
+ fprintf(fp,"%g %g\n",(j+0.5)*dz+opt->min,pot[j]);
+ ffclose(fp);
+ printf("verbose mode: wrote %s with PMF from interated forces\n","pmfintegrated.xvg");
+ }
+
+ /* get initial z=exp(-F[i]/kT) from integrated potential, where F[i] denote the free
+ energy offsets which are usually determined by wham
+ First: turn pot into probabilities:
+ */
+ for(j=0;j<opt->bins;++j)
+ pot[j]=exp(-pot[j]/(8.314e-3*opt->Temperature));
+ calc_z(pot,window,nWindows,opt,TRUE);
+
+ sfree(pot);
+ sfree(f);
+}
+
+
int gmx_wham(int argc,char *argv[])
{
const char *desc[] = {
- "This is an analysis program that implements the Weighted",
- "Histogram Analysis Method (WHAM). It is intended to analyze",
- "output files generated by umbrella sampling simulations to ",
- "compute a potential of mean force (PMF). [PAR]",
- "At present, three input modes are supported:[BR]",
- "[TT]*[tt] With option [TT]-it[tt], the user provides a file which contains the",
- " filenames of the umbrella simulation run-input files (tpr files),",
- " AND, with option -ix, a file which contains filenames of",
- " the pullx mdrun output files. The tpr and pullx files must",
- " be in corresponding order, i.e. the first tpr created the",
- " first pullx, etc.[BR]",
- "[TT]*[tt] Same as the previous input mode, except that the the user",
- " provides the pull force ouput file names (pullf.xvg) with option -if.",
- " From the pull force the position in the ubrella potential is",
- " computed. This does not work with tabulated umbrella potentials.",
- "[TT]*[tt] With option [TT]-ip[tt], the user provides filenames of (gzipped) pdo files, i.e.",
- " the gromacs 3.3 umbrella output files. If you have some unusual",
- " reaction coordinate you may also generate your own pdo files and",
- " feed them with the -ip option into to g_wham. The pdo file header",
- " must be similar to the folowing:[BR]",
- "[TT]# UMBRELLA 3.0[BR]",
- "# Component selection: 0 0 1[BR]",
- "# nSkip 1[BR]",
- "# Ref. Group 'TestAtom'[BR]",
- "# Nr. of pull groups 2[BR]",
- "# Group 1 'GR1' Umb. Pos. 5.0 Umb. Cons. 1000.0[BR]",
- "# Group 2 'GR2' Umb. Pos. 2.0 Umb. Cons. 500.0[BR]",
- "#####[tt][BR]",
- " Nr of pull groups, umbrella positions, force constants, and names",
- " may (of course) differ. Following the header, a time column and",
- " a data columns for each pull group follow (i.e. the displacement",
- " with respect to the umbrella center). Up to four pull groups are possible",
- " at present.[PAR]",
- "By default, the output files are[BR]",
- " [TT]-o[tt] PMF output file[BR]",
- " [TT]-hist[tt] histograms output file[PAR]",
- "The umbrella potential is assumed to be harmonic and the force constants are ",
- "read from the tpr or pdo files. If a non-harmonic umbrella force was applied ",
- "a tabulated potential can be provied with -tab.[PAR]",
- "WHAM OPTIONS[PAR]",
- " [TT]-bins[tt] Nr of bins used in analysis[BR]",
- " [TT]-temp[tt] Temperature in the simulations[BR]",
- " [TT]-tol[tt] Stop iteration if profile (probability) changed less than tolerance[BR]",
- " [TT]-auto[tt] Automatic determination of boudndaries[BR]",
- " [TT]-min,-max[tt] Boundaries of the profile [BR]",
- "The data points which are used ",
- "to compute the profile can be restricted with options -b, -e, and -dt. ",
- "Play particularly with -b to ensure sufficient equilibration in each ",
- "umbrella window![PAR]",
- "With -log (default) the profile is written in energy units, otherwise (-nolog) as ",
- "probability. The unit can be specified with -unit. With energy output, ",
- "the energy in the first bin is defined to be zero. If you want the free energy at a different ",
- "position to be zero, choose with -zprof0 (useful with bootstrapping, see below).[PAR]",
- "For cyclic (or periodic) reaction coordinates (dihedral angle, channel PMF",
- "without osmotic gradient), -cycl is useful.[BR]",
- "[TT]-cycl yes[tt] min and max are assumed to",
- "be neighboring points and histogram points outside min and max are mapped into ",
- "the interval [min,max] (compare histogram output). [BR]",
- "[TT]-cycl weighted[tt] First, a non-cyclic profile is computed. Subsequently, ",
- "periodicity is enforced by adding corrections dG(i) between neighboring bins",
- "i and i+1. The correction is chosen proportional to 1/[n(i)*n(i+1)]^alpha, where",
- "n(i) denotes the total nr of data points in bin i as collected from all histograms.",
- "alpha is defined with -alpha. The corrections are written to the file defined by -wcorr.",
- " (Compare Hub and de Groot, PNAS 105:1198 (2008))[PAR]",
- "ERROR ANALYSIS[BR]",
- "Statistical errors may be estimated with bootstrap analysis. Use it with care, ",
- "otherwise the statistical error may be substantially undererstimated !![BR]",
- "[TT]-nBootstrap[tt] defines the nr of bootstraps. Two bootstrapping modes are supported.[BR]",
- "[TT]-histbs[tt] Complete histograms are considered as independent data points (default). For each",
- "bootstrap, N histograms are randomly chosen from the N given histograms (allowing duplication).",
- "To avoid gaps without data along the reaction coordinate blocks of histograms (-histbs-block)",
- "may be defined. In that case, the given histograms are divided into blocks and ",
- "only histograms within each block are mixed. Note that the histograms",
- "within each block must be representative for all possible histograms, otherwise the",
- "statistical error is undererstimated![BR]",
- "[TT]-nohistbs[tt] The given histograms are used to generate new random histograms,",
- "such that the generated data points are distributed according the given histograms. The number",
- "of points generated for each bootstrap histogram can be controlled with -bs-dt.",
- "Note that one data point should be generated for each *independent* point in the given",
- "histograms. With the long autocorrelations in MD simulations, this procedure may ",
- "easily understimate the error![BR]",
- "Bootstrapping output:[BR]",
- "[TT]-bsres[tt] Average profile and standard deviations[BR]",
- "[TT]-bsprof[tt] All bootstrapping profiles[BR]",
- "With [TT]-vbs[tt] (verbose bootstrapping), the histograms of each bootstrap are written, and, ",
- "with [TT]-nohistBS[tt], the cummulants of the histogram.",
+ "This is an analysis program that implements the Weighted",
+ "Histogram Analysis Method (WHAM). It is intended to analyze",
+ "output files generated by umbrella sampling simulations to ",
+ "compute a potential of mean force (PMF). [PAR] ",
+ "At present, three input modes are supported.[BR]",
+ "[TT]*[tt] With option [TT]-it[tt], the user provides a file which contains the[BR]",
+ " file names of the umbrella simulation run-input files (tpr files),[BR]",
+ " AND, with option [TT]-ix[tt], a file which contains file names of [BR]",
+ " the pullx mdrun output files. The tpr and pullx files must [BR]",
+ " be in corresponding order, i.e. the first tpr created the [BR]",
+ " first pullx, etc.[BR]",
+ "[TT]*[tt] Same as the previous input mode, except that the the user [BR]",
+ " provides the pull force output file names (pullf.xvg) with option [TT]-if[tt].[BR]",
+ " From the pull force the position in the umbrella potential is [BR]",
+ " computed. This does not work with tabulated umbrella potentials.[BR]"
+ "[TT]*[tt] With option [TT]-ip[tt], the user provides file names of (gzipped) pdo files, i.e.[BR]",
+ " the gromacs 3.3 umbrella output files. If you have some unusual[BR]"
+ " reaction coordinate you may also generate your own pdo files and [BR]",
+ " feed them with the [TT]-ip[tt] option into to g_wham. The pdo file header [BR]",
+ " must be similar to the following:[BR]",
+ "[TT]# UMBRELLA 3.0[BR]",
+ "# Component selection: 0 0 1[BR]",
+ "# nSkip 1[BR]",
+ "# Ref. Group 'TestAtom'[BR]",
+ "# Nr. of pull groups 2[BR]",
+ "# Group 1 'GR1' Umb. Pos. 5.0 Umb. Cons. 1000.0[BR]",
+ "# Group 2 'GR2' Umb. Pos. 2.0 Umb. Cons. 500.0[BR]",
+ "#####[tt][BR]",
+ "Nr of pull groups, umbrella positions, force constants, and names ",
+ "may (of course) differ. Following the header, a time column and ",
+ "a data columns for each pull group follows (i.e. the displacement",
+ "with respect to the umbrella center). Up to four pull groups are possible ",
+ "per pdo file at present.[PAR]",
+ "By default, the output files are[BR]",
+ " [TT]-o[tt] PMF output file[BR]",
+ " [TT]-hist[tt] histograms output file[BR]",
+ "Always check whether the histograms sufficiently overlap![PAR]",
+ "The umbrella potential is assumed to be harmonic and the force constants are ",
+ "read from the tpr or pdo files. If a non-harmonic umbrella force was applied ",
+ "a tabulated potential can be provided with [TT]-tab[tt].[PAR]",
+ "WHAM OPTIONS[BR]------------[BR]",
+ " [TT]-bins[tt] Nr of bins used in analysis[BR]",
+ " [TT]-temp[tt] Temperature in the simulations[BR]",
+ " [TT]-tol[tt] Stop iteration if profile (probability) changed less than tolerance[BR]",
+ " [TT]-auto[tt] Automatic determination of boundaries[BR]",
+ " [TT]-min,-max[tt] Boundaries of the profile [BR]",
+ "The data points which are used ",
+ "to compute the profile can be restricted with options [TT]-b[tt], [TT]-e[tt], and [TT]-dt[tt]. ",
+ "Play particularly with [TT]-b[tt] to ensure sufficient equilibration in each ",
+ "umbrella window![PAR]",
+ "With [TT]-log[tt] (default) the profile is written in energy units, otherwise ([TT]-nolog[tt]) as ",
+ "probability. The unit can be specified with [TT]-unit[tt]. With energy output, ",
+ "the energy in the first bin is defined to be zero. If you want the free energy at a different ",
+ "position to be zero, choose with [TT]-zprof0[tt] (useful with bootstrapping, see below).[PAR]",
+ "For cyclic (or periodic) reaction coordinates (dihedral angle, channel PMF",
+ "without osmotic gradient), the option [TT]-cycl[tt] is useful. g_wham will make use of the ",
+ "periodicity of the system and generate a periodic PMF. The first and the last bin of the",
+ "reaction coordinate will assumed be be neighbors[PAR]",
+ "Option [TT]-sym[tt] symmetrizes the profile around z=0 before output (useful for membrane etc.)[PAR]",
+ "AUTOCORRELATIONS[BR]----------------[BR]",
+ "With [TT]-ac[tt], g_wham estimates the integrated autocorrelation time (IACT) tau for each ",
+ "umbrella window and weights the respective window with 1/[1+2*tau/dt]. The IACTs are written ",
+ "to the file defined with [TT]-oiact[tt]. In verbose mode, all autocorrelation functions (ACFs) are",
+ "written to hist_autocorr.xvg. Because the IACTs can be severely underestimated in case of ",
+ "limited sampling, option [TT]-acsig[tt] allows to smooth the IACTs along the reaction coordinate ",
+ "with a Gaussian (sigma provided with [TT]-acsig[tt], see output in iact.xvg). Note that the ",
+ "IACTs are estimated by simple integration of the ACFs while the ACFs are larger 0.05.",
+ "If you prefer to compute the IACTs by a more sophisticated (but possibly less robust) method ",
+ "such as fitting to a double exponential, you can compute the IACTs with g_analyze and provide",
+ "them to g_wham with the file iact-in.dat (option [TT]-iiact[tt]). iact-in.dat should contain ",
+ "one line per input file (pdo or pullx/f file) and one column per pull group in the respective file.[PAR]"
+ "ERROR ANALYSIS[BR]--------------[BR]",
+ "Statistical errors may be estimated with bootstrap analysis. Use it with care, ",
+ "otherwise the statistical error may be substantially underestimated !![BR]",
+ "More background and examples for the bootstrap technique can be found in ",
+ "Hub, de Groot and Van der Spoel, JCTC (2010)[BR]",
+ "-nBootstrap defines the nr of bootstraps (use, e.g., 100). Four bootstrapping methods are supported and ",
+ "selected with [TT]-bs-method[tt].[BR]",
+ " (1) [TT]b-hist[tt] Default: complete histograms are considered as independent data points, and ",
+ " the bootstrap is carried out by assigning random weights to the histograms (\"Bayesian bootstrap\").",
+ " Note that each point along the reaction coordinate",
+ "must be covered by multiple independent histograms (e.g. 10 histograms), otherwise the ",
+ "statistical error is underestimated![BR]",
+ " (2) [TT]hist[tt] Complete histograms are considered as independent data points. For each",
+ "bootstrap, N histograms are randomly chosen from the N given histograms (allowing duplication, i.e. ",
+ "sampling with replacement).",
+ "To avoid gaps without data along the reaction coordinate blocks of histograms ([TT]-histbs-block[tt])",
+ "may be defined. In that case, the given histograms are divided into blocks and ",
+ "only histograms within each block are mixed. Note that the histograms",
+ "within each block must be representative for all possible histograms, otherwise the",
+ "statistical error is underestimated![BR]",
+ " (3) [TT]traj[tt] The given histograms are used to generate new random trajectories,",
+ "such that the generated data points are distributed according the given histograms ",
+ "and properly autocorrelated. The ",
+ "autocorrelation time (ACT) for each window must be known, so use [TT]-ac[tt] or provide the ACT",
+ "with [TT]-iiact[TT]. If the ACT of all windows are identical (and known), you can also ",
+ "provide them with [TT]-bs-tau[tt]. Note that this method may severely underestimate the error ",
+ "in case of limited sampling, that is if individual histograms do not represent the complete",
+ "phase space at the respective positions.[BR]",
+ " (4) [TT]traj-gauss[tt] The same as Method [TT]traj[tt], but the trajectories are not bootstrapped ",
+ "from the umbrella histograms but from Gaussians with the average and width of the umbrella ",
+ "histograms. That method yields similar error estimates like method [TT]traj[tt].[BR]"
+ "Bootstrapping output:[BR]",
+ " [TT]-bsres[tt] Average profile and standard deviations[BR]",
+ " [TT]-bsprof[tt] All bootstrapping profiles[BR]",
+ "With [TT]-vbs[tt] (verbose bootstrapping), the histograms of each bootstrap are written, and, ",
+ "with bootstrap method [TT]traj[tt], the cumulative distribution functions of the histograms.",
};
- static t_UmbrellaOptions opt;
- static gmx_bool bHistOnly=FALSE;
-
const char *en_unit[]={NULL,"kJ","kCal","kT",NULL};
- const char *en_unit_label[]={"","E (kJ mol\\S-1\\N)","E (kcal mol\\S-1\\N)","E (kT)",};
- const char *en_cycl[]={NULL,"no","yes","weighted",NULL};
-
+ const char *en_unit_label[]={"","E (kJ mol\\S-1\\N)","E (kcal mol\\S-1\\N)","E (kT)",NULL};
+ const char *en_bsMethod[]={ NULL,"b-hist", "hist", "traj", "traj-gauss", NULL };
+
+ static t_UmbrellaOptions opt;
+
t_pargs pa[] = {
- { "-min", FALSE, etREAL, {&opt.min},
- "Minimum coordinate in profile"},
- { "-max", FALSE, etREAL, {&opt.max},
- "Maximum coordinate in profile"},
- { "-auto", FALSE, etBOOL, {&opt.bAuto},
- "determine min and max automatically"},
- { "-bins",FALSE, etINT, {&opt.bins},
- "Number of bins in profile"},
- { "-temp", FALSE, etREAL, {&opt.Temperature},
- "Temperature"},
- { "-tol", FALSE, etREAL, {&opt.Tolerance},
- "Tolerance"},
- { "-v", FALSE, etBOOL, {&opt.verbose},
- "verbose mode"},
- { "-b", FALSE, etREAL, {&opt.tmin},
- "first time to analyse (ps)"},
- { "-e", FALSE, etREAL, {&opt.tmax},
- "last time to analyse (ps)"},
- { "-dt", FALSE, etREAL, {&opt.dt},
- "Analyse only every dt ps"},
- { "-histonly", FALSE, etBOOL, {&bHistOnly},
- "Write histograms and exit"},
- { "-boundsonly", FALSE, etBOOL, {&opt.bBoundsOnly},
- "Determine min and max and exit (with -auto)"},
- { "-log", FALSE, etBOOL, {&opt.bLog},
- "Calculate the log of the profile before printing"},
- { "-unit", FALSE, etENUM, {en_unit},
- "energy unit in case of log output" },
- { "-zprof0", FALSE, etREAL, {&opt.zProf0},
- "Define profile to 0.0 at this position (with -log)"},
- { "-cycl", FALSE, etENUM, {en_cycl},
- "Create cyclic/periodic profile. Assumes min and max are the same point."},
- { "-alpha", FALSE, etREAL, {&opt.alpha},
- "for '-cycl weighted', set parameter alpha"},
- { "-flip", FALSE, etBOOL, {&opt.bFlipProf},
- "Combine halves of profile (not supported)"},
- { "-hist-eq", FALSE, etBOOL, {&opt.bHistEq},
- "Enforce equal weight for all histograms. (Non-Weighed-HAM)"},
- { "-nBootstrap", FALSE, etINT, {&opt.nBootStrap},
- "nr of bootstraps to estimate statistical uncertainty" },
- { "-bs-dt", FALSE, etREAL, {&opt.dtBootStrap},
- "timestep for synthetic bootstrap histograms (ps). Ensure independent data points!"},
- { "-bs-seed", FALSE, etINT, {&opt.bsSeed},
- "seed for bootstrapping. (-1 = use time)"},
- { "-histbs", FALSE, etBOOL, {&opt.bHistBootStrap},
- "In bootstrapping, consider complete histograms as one data point. "
- "Accounts better for long autocorrelations."},
- { "-histbs-block", FALSE, etINT, {&opt.histBootStrapBlockLength},
- "when mixin histograms only mix within blocks of -histBS_block."},
- { "-vbs", FALSE, etBOOL, {&opt.bs_verbose},
- "verbose bootstrapping. Print the cummulants and a histogram file for each bootstrap."},
+ { "-min", FALSE, etREAL, {&opt.min},
+ "Minimum coordinate in profile"},
+ { "-max", FALSE, etREAL, {&opt.max},
+ "Maximum coordinate in profile"},
+ { "-auto", FALSE, etBOOL, {&opt.bAuto},
+ "determine min and max automatically"},
+ { "-bins",FALSE, etINT, {&opt.bins},
+ "Number of bins in profile"},
+ { "-temp", FALSE, etREAL, {&opt.Temperature},
+ "Temperature"},
+ { "-tol", FALSE, etREAL, {&opt.Tolerance},
+ "Tolerance"},
+ { "-v", FALSE, etBOOL, {&opt.verbose},
+ "verbose mode"},
+ { "-b", FALSE, etREAL, {&opt.tmin},
+ "first time to analyse (ps)"},
+ { "-e", FALSE, etREAL, {&opt.tmax},
+ "last time to analyse (ps)"},
+ { "-dt", FALSE, etREAL, {&opt.dt},
+ "Analyse only every dt ps"},
+ { "-histonly", FALSE, etBOOL, {&opt.bHistOnly},
+ "Write histograms and exit"},
+ { "-boundsonly", FALSE, etBOOL, {&opt.bBoundsOnly},
+ "Determine min and max and exit (with -auto)"},
+ { "-log", FALSE, etBOOL, {&opt.bLog},
+ "Calculate the log of the profile before printing"},
+ { "-unit", FALSE, etENUM, {en_unit},
+ "energy unit in case of log output" },
+ { "-zprof0", FALSE, etREAL, {&opt.zProf0},
+ "Define profile to 0.0 at this position (with -log)"},
+ { "-cycl", FALSE, etBOOL, {&opt.bCycl},
+ "Create cyclic/periodic profile. Assumes min and max are the same point."},
+ { "-sym", FALSE, etBOOL, {&opt.bSym},
+ "symmetrize profile around z=0"},
+ { "-hist-eq", FALSE, etBOOL, {&opt.bHistEq},
+ "HIDDENEnforce equal weight for all histograms. (Non-Weighed-HAM)"},
+ { "-ac", FALSE, etBOOL, {&opt.bCalcTauInt},
+ "calculate integrated autocorrelation times and use in wham"},
+ { "-acsig", FALSE, etREAL, {&opt.sigSmoothIact},
+ "Smooth autocorrelation times along reaction coordinate with Gaussian of this sigma"},
+ { "-ac-trestart", FALSE, etREAL, {&opt.acTrestart},
+ "When computing autocorrelation functions, restart computing every .. (ps)"},
+ { "-acred", FALSE, etBOOL, {&opt.bAllowReduceIact},
+ "HIDDENWhen smoothing the ACTs, allow to reduce ACTs. Otherwise, only increase ACTs "
+ "during smoothing"},
+ { "-nBootstrap", FALSE, etINT, {&opt.nBootStrap},
+ "nr of bootstraps to estimate statistical uncertainty (e.g., 200)" },
+ { "-bs-method", FALSE, etENUM, {en_bsMethod},
+ "bootstrap method" },
+ { "-bs-tau", FALSE, etREAL, {&opt.tauBootStrap},
+ "Autocorrelation time (ACT) assumed for all histograms. Use option -ac if ACT is unknown."},
+ { "-bs-seed", FALSE, etINT, {&opt.bsSeed},
+ "seed for bootstrapping. (-1 = use time)"},
+ { "-histbs-block", FALSE, etINT, {&opt.histBootStrapBlockLength},
+ "when mixing histograms only mix within blocks of -histbs-block."},
+ { "-vbs", FALSE, etBOOL, {&opt.bs_verbose},
+ "verbose bootstrapping. Print the CDFs and a histogram file for each bootstrap."},
+ { "-stepout", FALSE, etINT, {&opt.stepchange},
+ "HIDDENWrite maximum change every ... (set to 1 with -v)"},
+ { "-updateContr", FALSE, etINT, {&opt.stepUpdateContrib},
+ "HIDDENUpdate table with significan contributions to WHAM every ... iterations"},
};
-
+
t_filenm fnm[] = {
- { efDAT, "-ix","pullx-files",ffOPTRD}, /* wham input: pullf.xvg's and tprs */
- { efDAT, "-if","pullf-files",ffOPTRD}, /* wham input: pullf.xvg's and tprs */
- { efDAT, "-it","tpr-files",ffOPTRD}, /* wham input: tprs */
- { efDAT, "-ip","pdo-files",ffOPTRD}, /* wham input: pdo files (gmx3 style) */
- { efXVG, "-o", "profile", ffWRITE }, /* output file for profile */
- { efXVG, "-hist","histo", ffWRITE}, /* output file for histograms */
- { efXVG, "-bsres","bsResult", ffOPTWR}, /* average and errors of bootstrap analysis */
- { efXVG, "-bsprof","bsProfs", ffOPTWR}, /* output file for bootstrap profiles */
- { efDAT, "-tab","umb-pot",ffOPTRD}, /* Tabulated umbrella potential (if not harmonic) */
- { efXVG, "-wcorr","cycl-corr",ffOPTRD}, /* Corrections to profile in case -cycl weighted */
+ { efDAT, "-ix","pullx-files",ffOPTRD}, /* wham input: pullf.xvg's and tprs */
+ { efDAT, "-if","pullf-files",ffOPTRD}, /* wham input: pullf.xvg's and tprs */
+ { efDAT, "-it","tpr-files",ffOPTRD}, /* wham input: tprs */
+ { efDAT, "-ip","pdo-files",ffOPTRD}, /* wham input: pdo files (gmx3 style) */
+ { efXVG, "-o", "profile", ffWRITE }, /* output file for profile */
+ { efXVG, "-hist","histo", ffWRITE}, /* output file for histograms */
+ { efXVG, "-oiact","iact",ffOPTWR}, /* writing integrated autocorrelation times */
+ { efDAT, "-iiact","iact-in",ffOPTRD}, /* reading integrated autocorrelation times */
+ { efXVG, "-bsres","bsResult", ffOPTWR}, /* average and errors of bootstrap analysis */
+ { efXVG, "-bsprof","bsProfs", ffOPTWR}, /* output file for bootstrap profiles */
+ { efDAT, "-tab","umb-pot",ffOPTRD}, /* Tabulated umbrella potential (if not harmonic) */
};
-
+
int i,j,l,nfiles,nwins,nfiles2;
t_UmbrellaHeader header;
t_UmbrellaWindow * window=NULL;
char **fninTpr,**fninPull,**fninPdo;
const char *fnPull;
FILE *histout,*profout;
- char ylabel[256],title[256];
- output_env_t oenv;
+ char ylabel[256],title[256];
+
+#define NFILE asize(fnm)
+
+ CopyRight(stderr,argv[0]);
opt.bins=200;
opt.verbose=FALSE;
- opt.cycl=enCycl_no;
+ opt.bHistOnly=FALSE;
+ opt.bCycl=FALSE;
opt.tmin=50;
opt.tmax=1e20;
opt.dt=0.0;
- opt.bShift=TRUE;
- opt.nBootStrap=0;
- opt.dtBootStrap=0.0;
- opt.bsSeed=-1;
- opt.bHistBootStrap=TRUE;
- opt.histBootStrapBlockLength=12;
- opt.zProfZero=0.0;
- opt.bWeightedCycl=FALSE;
- opt.alpha=2;
- opt.bHistOutOnly=FALSE;
opt.min=0;
opt.max=0;
- opt.bLog=TRUE;
- opt.unit=en_kJ;
- opt.zProf0=0.0;
+ opt.bAuto=TRUE;
+
+ /* bootstrapping stuff */
opt.nBootStrap=0;
+ opt.bsMethod=bsMethod_hist;
+ opt.tauBootStrap=0.0;
opt.bsSeed=-1;
- opt.bHistBootStrap=TRUE;
opt.histBootStrapBlockLength=8;
opt.bs_verbose=FALSE;
+
+ opt.bLog=TRUE;
+ opt.unit=en_kJ;
+ opt.zProf0=0.;
opt.Temperature=298;
- opt.bFlipProf=FALSE;
opt.Tolerance=1e-6;
- opt.bAuto=TRUE;
opt.bBoundsOnly=FALSE;
+ opt.bSym=FALSE;
+ opt.bCalcTauInt=FALSE;
+ opt.sigSmoothIact=0.0;
+ opt.bAllowReduceIact=TRUE;
+ opt.bInitPotByIntegration=TRUE;
+ opt.acTrestart=1.0;
+ opt.stepchange=100;
+ opt.stepUpdateContrib=100;
-
-#define NFILE asize(fnm)
-
- CopyRight(stderr,argv[0]);
parse_common_args(&argc,argv,PCA_BE_NICE,
- NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL,&oenv);
-
+ NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL,&opt.oenv);
+
opt.unit=nenum(en_unit);
- opt.cycl=nenum(en_cycl);
+ opt.bsMethod=nenum(en_bsMethod);
opt.bProf0Set=opt2parg_bSet("-zprof0", asize(pa), pa);
-
+
opt.bTab=opt2bSet("-tab",NFILE,fnm);
opt.bPdo=opt2bSet("-ip",NFILE,fnm);
opt.bTpr=opt2bSet("-it",NFILE,fnm);
opt.bPullx=opt2bSet("-ix",NFILE,fnm);
opt.bPullf=opt2bSet("-if",NFILE,fnm);
+ opt.bTauIntGiven=opt2bSet("-iiact",NFILE,fnm);
if (opt.bTab && opt.bPullf)
gmx_fatal(FARGS,"Force input does not work with tabulated potentials. "
- "Provide pullx.xvg or pdo files!");
+ "Provide pullx.xvg or pdo files!");
-#define BOOLXOR(a,b) ( ((!(a))&&(b)) || ((a)&&(!(b))))
- if (!opt.bPdo && !BOOLXOR(opt.bPullx,opt.bPullf))
+#define WHAMBOOLXOR(a,b) ( ((!(a))&&(b)) || ((a)&&(!(b))))
+ if (!opt.bPdo && !WHAMBOOLXOR(opt.bPullx,opt.bPullf))
gmx_fatal(FARGS,"Give either pullx (-ix) OR pullf (-if) data. Not both.");
if ( !opt.bPdo && !(opt.bTpr || opt.bPullf || opt.bPullx))
gmx_fatal(FARGS,"g_wham supports three input modes, pullx, pullf, or pdo file input."
- "\n\n Check g_wham -h !");
-
+ "\n\n Check g_wham -h !");
+
opt.fnPdo=opt2fn("-ip",NFILE,fnm);
opt.fnTpr=opt2fn("-it",NFILE,fnm);
opt.fnPullf=opt2fn("-if",NFILE,fnm);
opt.bAuto=FALSE;
}
+ if (opt.bTauIntGiven && opt.bCalcTauInt)
+ gmx_fatal(FARGS,"Either read (option -iiact) or calculate (option -ac) the\n"
+ "the autocorrelation times. Not both.");
+
+ if (opt.tauBootStrap>0.0 && opt2parg_bSet("-ac",asize(pa), pa))
+ gmx_fatal(FARGS,"Either compute autocorrelation times (ACTs) (option -ac) or "
+ "provide it with -bs-tau for bootstrapping. Not Both.\n");
+ if (opt.tauBootStrap>0.0 && opt2bSet("-iiact",NFILE,fnm))
+ gmx_fatal(FARGS,"Either provide autocorrelation times (ACTs) with file iact-in.dat "
+ "(option -iiact) or define all ACTs with -bs-tau for bootstrapping\n. Not Both.");
+
+
/* Reading gmx4 pull output and tpr files */
if (opt.bTpr || opt.bPullf || opt.bPullx)
{
read_wham_in(opt.fnTpr,&fninTpr,&nfiles,&opt);
-
+
fnPull=opt.bPullf ? opt.fnPullf : opt.fnPullx;
read_wham_in(fnPull,&fninPull,&nfiles2,&opt);
printf("Found %d tpr and %d pull %s files in %s and %s, respectively\n",
- nfiles,nfiles2,opt.bPullf ? "force" : "position",opt.fnTpr,fnPull);
+ nfiles,nfiles2,opt.bPullf ? "force" : "position",opt.fnTpr,fnPull);
if (nfiles!=nfiles2)
gmx_fatal(FARGS,"Found %d file names in %s, but %d in %s\n",nfiles,
- opt.fnTpr,nfiles2,fnPull);
- read_tpr_pullxf_files(fninTpr,fninPull,nfiles, &header, &window, &opt);
+ opt.fnTpr,nfiles2,fnPull);
+ window=initUmbrellaWindows(nfiles);
+ read_tpr_pullxf_files(fninTpr,fninPull,nfiles, &header, window, &opt);
}
else
- {
- /* reading pdo files */
+ { /* reading pdo files */
read_wham_in(opt.fnPdo,&fninPdo,&nfiles,&opt);
printf("Found %d pdo files in %s\n",nfiles,opt.fnPdo);
- read_pdo_files(fninPdo,nfiles, &header, &window, &opt);
+ window=initUmbrellaWindows(nfiles);
+ read_pdo_files(fninPdo,nfiles, &header, window, &opt);
}
- nwins=nfiles;
+ nwins=nfiles;
/* enforce equal weight for all histograms? */
if (opt.bHistEq)
/* write histograms */
histout=xvgropen(opt2fn("-hist",NFILE,fnm),"Umbrella histograms",
- "z","count",oenv);
- for(l=0;l<opt.bins;++l)
+ "z","count",opt.oenv);
+ for(l=0;l<opt.bins;++l)
{
fprintf(histout,"%e\t",(double)(l+0.5)/opt.bins*(opt.max-opt.min)+opt.min);
- for(i=0;i<nwins;++i)
- {
- for(j=0;j<window[i].nPull;++j)
+ for(i=0;i<nwins;++i)
+ {
+ for(j=0;j<window[i].nPull;++j)
{
fprintf(histout,"%e\t",window[i].Histo[j][l]);
}
fprintf(histout,"\n");
}
ffclose(histout);
- if (bHistOnly)
+ printf("Wrote %s\n",opt2fn("-hist",NFILE,fnm));
+ if (opt.bHistOnly)
{
printf("Wrote histograms to %s, now exiting.\n",opt2fn("-hist",NFILE,fnm));
return 0;
/* Using tabulated umbrella potential */
if (opt.bTab)
setup_tab(opt2fn("-tab",NFILE,fnm),&opt);
-
- setup_acc_wham(window,nwins,&opt);
+
+ /* Integrated autocorrelation times provided ? */
+ if (opt.bTauIntGiven)
+ readIntegratedAutocorrelationTimes(window,nwins,&opt,opt2fn("-iiact",NFILE,fnm));
+
+ /* Compute integrated autocorrelation times */
+ if (opt.bCalcTauInt)
+ calcIntegratedAutocorrelationTimes(window,nwins,&opt,opt2fn("-oiact",NFILE,fnm));
+
+ /* calc average and sigma for each histogram
+ (maybe required for bootstrapping. If not, this is fast anyhow) */
+ if (opt.nBootStrap && opt.bsMethod==bsMethod_trajGauss)
+ averageSigma(window,nwins,&opt);
+
+ /* Get initial potential by simple integration */
+ if (opt.bInitPotByIntegration)
+ guessPotByIntegration(window,nwins,&opt,0);
+
+ /* Check if complete reaction coordinate is covered */
+ checkReactionCoordinateCovered(window,nwins,&opt);
/* Calculate profile */
- snew(profile,opt.bins);
- opt.stepchange=(opt.verbose)? 1 : 100;
+ snew(profile,opt.bins);
+ if (opt.verbose)
+ opt.stepchange=1;
i=0;
- do {
+ do
+ {
+ if ( (i%opt.stepUpdateContrib) == 0)
+ setup_acc_wham(profile,window,nwins,&opt);
if (maxchange<opt.Tolerance)
{
bExact=TRUE;
if (((i%opt.stepchange) == 0 || i==1) && !i==0)
printf("\t%4d) Maximum change %e\n",i,maxchange);
i++;
- } while( (maxchange=calc_z(profile, window, nwins, &opt,bExact)) > opt.Tolerance || !bExact);
+ } while ( (maxchange=calc_z(profile, window, nwins, &opt,bExact)) > opt.Tolerance || !bExact);
printf("Converged in %d iterations. Final maximum change %g\n",i,maxchange);
+ /* calc error from Kumar's formula */
+ /* Unclear how the error propagates along reaction coordinate, therefore
+ commented out */
+ /* calc_error_kumar(profile,window, nwins,&opt); */
+
/* Write profile in energy units? */
if (opt.bLog)
{
strcpy(ylabel,"Density of states");
strcpy(title,"Density of states");
}
- /* Force cyclic profile by wheighted correction? */
- if (opt.cycl==enCycl_weighted)
- cyclicProfByWeightedCorr(profile,window,nwins,&opt,TRUE,
- opt2fn("-wcorr",NFILE,fnm),oenv);
+
+ /* symmetrize profile around z=0? */
+ if (opt.bSym)
+ symmetrizeProfile(profile,&opt);
- profout=xvgropen(opt2fn("-o",NFILE,fnm),title,"z",ylabel,oenv);
+ /* write profile or density of states */
+ profout=xvgropen(opt2fn("-o",NFILE,fnm),title,"z",ylabel,opt.oenv);
for(i=0;i<opt.bins;++i)
- fprintf(profout,"%e\t%e\n",
- (double)(i+0.5)/opt.bins*(opt.max-opt.min)+opt.min,profile[i]);
+ fprintf(profout,"%e\t%e\n",(double)(i+0.5)/opt.bins*(opt.max-opt.min)+opt.min,profile[i]);
ffclose(profout);
printf("Wrote %s\n",opt2fn("-o",NFILE,fnm));
-
+
/* Bootstrap Method */
if (opt.nBootStrap)
- do_bootstrapping(opt2fn("-bsres",NFILE,fnm),opt2fn("-bsprof",NFILE,fnm),
- opt2fn("-hist",NFILE,fnm),
- ylabel, profile, window, nwins, &opt,oenv);
+ do_bootstrapping(opt2fn("-bsres",NFILE,fnm),opt2fn("-bsprof",NFILE,fnm),
+ opt2fn("-hist",NFILE,fnm),
+ ylabel, profile, window, nwins, &opt);
+
+ sfree(profile);
+ freeUmbrellaWindows(window,nfiles);
+
+ printf("\nIn case you use results from g_wham for a publication, please cite:\n");
+ please_cite(stdout,"Hub2010");
thanx(stderr);
return 0;
extern t_dlist *mk_dlist(FILE *log,
t_atoms *atoms, int *nlist,
gmx_bool bPhi, gmx_bool bPsi, gmx_bool bChi, int maxchi,
- int r0,int naa,char **aa);
+ int r0, gmx_residuetype_t rt);
extern void pr_dlist(FILE *fp,int nl,t_dlist dl[],real dt, int printtype,
gmx_bool bPhi, gmx_bool bPsi,gmx_bool bChi,gmx_bool bOmega, int maxchi);