cmake_minimum_required(VERSION 2.8)
+# Keep CMake suitably quiet on Cygwin
+set(CMAKE_LEGACY_CYGWIN_WIN32 0) # Remove when CMake >= 2.8.4 is required
project(Gromacs)
include(Dart)
check_function_exists(_fileno HAVE__FILENO)
check_function_exists(fileno HAVE_FILENO)
check_function_exists(_commit HAVE__COMMIT)
+check_function_exists(sigaction HAVE_SIGACTION)
include(CheckLibraryExists)
check_library_exists(m sqrt "" HAVE_LIBM)
set(GMX_CYGWIN 1)
endif(CYGWIN)
+if(WIN32 AND NOT CYGWIN)
+ set(GMX_NATIVE_WINDOWS 1)
+endif()
+
# only bother with finding git and using version.h if the source is a git repo
if(EXISTS "${CMAKE_SOURCE_DIR}/.git")
if(USE_VERSION_H)
add_definitions( -DHAVE_CONFIG_H )
include_directories(${CMAKE_BINARY_DIR}/src)
+include_directories(${CMAKE_BINARY_DIR}/include)
include_directories(${CMAKE_SOURCE_DIR}/include)
include(gmxCheckBuildUserTime)
set(GMX_FFT_FFTW3 1)
+ if (${GMX_ACCELERATION} STREQUAL "SSE" AND NOT FFTW_HAVE_SSE)
+ message(WARNING "The fftw library found is compiled without SSE support, which makes it slow. Consider recompiling it or contact your admin")
+ endif (${GMX_ACCELERATION} STREQUAL "SSE" AND NOT FFTW_HAVE_SSE)
+
elseif(${GMX_FFT_LIBRARY} STREQUAL "MKL")
# MESSAGE(STATUS "Using external FFT library - Intel MKL")
find_package(MKL REQUIRED)
# FFTW_INCLUDE_DIRS - where to find FFTW headers
# FFTW_LIBRARIES - List of libraries when using FFTW.
# FFTW_PKG - The name of the pkg-config package needed
+# FFTW_HAVE_SSE - True if FFTW was build with SSE support
# FFTW_FOUND - True if FFTW was found
#
# This file is part of Gromacs Copyright (c) 2012
message(FATAL_ERROR "We do not support finding ${FFTW_FIND_COMPONENTS}, go and implement it ;-)")
endif()
-if(NOT __pkg_config_checked_PC_FFTW)
- pkg_check_modules(PC_FFTW "${FFTW_PKG}")
-endif(NOT __pkg_config_checked_PC_FFTW)
+if(NOT __pkg_config_checked_PC_FFTW_${FFTW_PKG})
+ pkg_check_modules(PC_FFTW_${FFTW_PKG} "${FFTW_PKG}")
+endif(NOT __pkg_config_checked_PC_FFTW_${FFTW_PKG})
-find_path(FFTW_INCLUDE_DIR_${FFTW_PKG} "${FFTW_HEADER}" HINTS ${PC_FFTW_INCLUDE_DIRS})
-find_library(FFTW_LIBRARY_${FFTW_PKG} NAMES "${FFTW_PKG}" HINTS ${PC_FFTW_LIBRARY_DIRS} )
+if(FFTW_LIBRARY)
+ set(FFTW_LIBRARY_${FFTW_PKG} "${FFTW_LIBRARY}" CACHE INTERNAL "Path to ${FFTW_PKG} library" FORCE)
+endif(FFTW_LIBRARY)
-#make _${FFTW_PKG} variables INTERNAL to avoid confusion
-set(FFTW_LIBRARY_${FFTW_PKG} ${FFTW_LIBRARY_${FFTW_PKG}} CACHE INTERNAL "Path to library ${FFTW_PKG}")
-set(FFTW_INCLUDE_DIR_${FFTW_PKG} ${FFTW_INCLUDE_DIR_${FFTW_PKG}} CACHE INTERNAL "Path to ${FFTW_HEADER}")
+if(FFTW_INCLUDE_DIR)
+ set(FFTW_INCLUDE_DIR_${FFTW_PKG} "${FFTW_INCLUDE_DIR}" CACHE INTERNAL "Path to ${FFTW_HEADER}" FORCE)
+endif(FFTW_INCLUDE_DIR)
-set(FFTW_LIBRARY ${FFTW_LIBRARY_${FFTW_PKG}} CACHE STRING "Path to library ${FFTW_PKG}")
-set(FFTW_INCLUDE_DIR ${FFTW_INCLUDE_DIR_${FFTW_PKG}} CACHE STRING "Path to ${FFTW_HEADER}")
+#we use _${FFTW_PKG} variables to have different cache entries for fftw3 and ffw3f
+find_path(FFTW_INCLUDE_DIR_${FFTW_PKG} "${FFTW_HEADER}" HINTS ${PC_FFTW_${FFTW_PKG}_INCLUDE_DIRS})
+find_library(FFTW_LIBRARY_${FFTW_PKG} NAMES "${FFTW_PKG}" HINTS ${PC_FFTW_${FFTW_PKG}_LIBRARY_DIRS})
-set(FFTW_LIBRARIES ${FFTW_LIBRARY} )
-set(FFTW_INCLUDE_DIRS ${FFTW_INCLUDE_DIR} )
+#make _${FFTW_PKG} variables INTERNAL to avoid confusion in cmake-gui
+set(FFTW_LIBRARY_${FFTW_PKG} ${FFTW_LIBRARY_${FFTW_PKG}} CACHE INTERNAL "Path to ${FFTW_PKG} library" FORCE)
+set(FFTW_INCLUDE_DIR_${FFTW_PKG} ${FFTW_INCLUDE_DIR_${FFTW_PKG}} CACHE INTERNAL "Path to ${FFTW_HEADER}" FORCE)
-include(FindPackageHandleStandardArgs)
-# handle the QUIETLY and REQUIRED arguments and set FFTW_FOUND to TRUE
-# if all listed variables are TRUE
+set(FFTW_LIBRARY "${FFTW_LIBRARY_${FFTW_PKG}}" CACHE FILEPATH "Path to ${FFTW_PKG} library" FORCE)
+set(FFTW_INCLUDE_DIR "${FFTW_INCLUDE_DIR_${FFTW_PKG}}" CACHE DIRECTORY "Path to ${FFTW_HEADER}" FORCE)
-find_package_handle_standard_args(FFTW DEFAULT_MSG FFTW_LIBRARY FFTW_INCLUDE_DIR )
+# set default find_package outcome variables
+set(FFTW_LIBRARIES "${FFTW_LIBRARY_${FFTW_PKG}}")
+set(FFTW_INCLUDE_DIRS "${FFTW_INCLUDE_DIR_${FFTW_PKG}}")
-if (FFTW_FOUND AND HAVE_LIBM)
+set(FFTW_FOUND FALSE)
+if (FFTW_LIBRARY_${FFTW_PKG} AND FFTW_INCLUDE_DIR_${FFTW_PKG})
+ set(FFTW_FOUND TRUE)
+elseif (NOT FFTW_LIBRARY_${FFTW_PKG})
+ message("Could not find ${FFTW_PKG} library named lib${FFTW_PKG}, please specify its location in FFTW_LIBRARY by hand (e.g. -DFFTW_LIBRARY='/path/to/lib${FFTW_PKG}.so')")
+elseif (NOT FFTW_INCLUDE_DIR_${FFTW_PKG})
+ message("Could not the ${FFTW_PKG} header ${FFTW_HEADER}, please specify its path in FFTW_INCLUDE_DIR by hand (e.g. -DFFTW_INCLUDE_DIR='/path/to/include')")
+endif()
+
+set(FFTW_HAVE_SSE FALSE CACHE BOOL "If ${FFTW_PKG} was built with SSE support")
+if (FFTW_FOUND AND HAVE_LIBM AND NOT "${FFTW_LIBRARY_PREVIOUS}" STREQUAL "${FFTW_LIBRARY}")
+ #The user could specify trash in FFTW_LIBRARY, so test if we can link it
include(CheckLibraryExists)
#adding MATH_LIBRARIES here to allow static libs, this does not harm us as we are anyway using it
- check_library_exists("${FFTW_LIBRARIES};m" "${FFTW_FUNCTION}" "" FOUND_FFTW_PLAN)
- if(NOT FOUND_FFTW_PLAN)
- message(FATAL_ERROR "Could not find ${FFTW_FUNCTION} in ${FFTW_LIBRARY}, take a look at the error message in ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log to find out what was going wrong. If you are using a static lib (.a) make sure you have specified all dependencies of ${FFTW_PKG} in FFTW_LIBRARY by hand (e.g. -DFFTW_LIBRARY='/path/to/lib${FFTW_PKG}.so;/path/to/libm.so') !")
- endif(NOT FOUND_FFTW_PLAN)
-endif (FFTW_FOUND AND HAVE_LIBM)
+ set(CMAKE_REQUIRED_LIBRARIES m)
+ unset(FOUND_FFTW_PLAN_${FFTW_PKG} CACHE)
+ check_library_exists("${FFTW_LIBRARIES}" "${FFTW_FUNCTION}" "" FOUND_FFTW_PLAN_${FFTW_PKG})
+ if(NOT FOUND_FFTW_PLAN_${FFTW_PKG})
+ message(FATAL_ERROR "Could not find ${FFTW_FUNCTION} in ${FFTW_LIBRARY_${FFTW_PKG}}, take a look at the error message in ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log to find out what went wrong. If you are using a static lib (.a) make sure you have specified all dependencies of ${FFTW_PKG} in FFTW_LIBRARY by hand (e.g. -DFFTW_LIBRARY='/path/to/lib${FFTW_PKG}.so;/path/to/libm.so') !")
+ endif(NOT FOUND_FFTW_PLAN_${FFTW_PKG})
+ #in 3.3 sse function name has changed
+ foreach(SSE_FCT fftwf_have_simd_sse2;fftw_have_simd_sse2;fftwf_have_sse;fftw_have_sse2)
+ unset(FFTW_HAVE_${SSE_FCT}_${FFTW_PKG} CACHE)
+ check_library_exists("${FFTW_LIBRARIES}" "${SSE_FCT}" "" FFTW_HAVE_${SSE_FCT}_${FFTW_PKG})
+ if(FFTW_HAVE_${SSE_FCT}_${FFTW_PKG})
+ set(FFTW_HAVE_SSE_${FFTW_PKG} "${FFTW_HAVE_${SSE_FCT}_${FFTW_PKG}}")
+ break()
+ endif(FFTW_HAVE_${SSE_FCT}_${FFTW_PKG})
+ endforeach()
+ set(FFTW_HAVE_SSE "${FFTW_HAVE_SSE_${FFTW_PKG}}" CACHE BOOL "If ${FFTW_PKG} was built with SSE support" FORCE)
+ set(CMAKE_REQUIRED_LIBRARIES)
+ set(FFTW_LIBRARY_PREVIOUS "${FFTW_LIBRARY}" CACHE INTERNAL "Value of FFTW_LIBRARY when executing the linking check that last time" FORCE)
+endif (FFTW_FOUND AND HAVE_LIBM AND NOT "${FFTW_LIBRARY_PREVIOUS}" STREQUAL "${FFTW_LIBRARY}")
-mark_as_advanced(FFTW_INCLUDE_DIR FFTW_LIBRARY )
+mark_as_advanced(FFTW_INCLUDE_DIR FFTW_LIBRARY FFTW_HAVE_SSE)
-# includes: Nothing to build, just installation
+# includes: Nothing to build, just configuration and installation
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/gmxconfig.h.cmakein ${CMAKE_CURRENT_BINARY_DIR}/gmxconfig.h)
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/gmxconfig.h
+ DESTINATION ${INCL_INSTALL_DIR}/gromacs
+ COMPONENT development
+)
+
install(DIRECTORY . DESTINATION ${INCL_INSTALL_DIR}/gromacs
COMPONENT development
PATTERN "Makefile*" EXCLUDE
PATTERN "CMake*" EXCLUDE
PATTERN "cmake*" EXCLUDE
PATTERN "*~" EXCLUDE
+ PATTERN "*.cmakein" EXCLUDE
)
--- /dev/null
+/* This include file will be configured by CMake and
+ * installed with GROMACS header files so that they can
+ * refer to a central location for #defines that will be
+ * available for builds of projects that depend on GROMACS.
+ */
+
+/* Detect native (i.e. non-Cygwin) Windows */
+#cmakedefine GMX_NATIVE_WINDOWS
}
}
+static void gmx_signal(int signum)
+{
+#ifdef HAVE_SIGACTION
+ struct sigaction act;
+ act.sa_handler = signal_handler;
+ act.flags = SA_RESTART;
+ sigaction(signum,act);
+#else
+ signal(signum,signal_handler);
+#endif
+}
void signal_handler_install(void)
{
{
fprintf(debug,"Installing signal handler for SIGTERM\n");
}
- signal(SIGTERM,signal_handler);
+ gmx_signal(SIGTERM);
}
if (getenv("GMX_NO_INT") == NULL)
{
{
fprintf(debug,"Installing signal handler for SIGINT\n");
}
- signal(SIGINT,signal_handler);
+ gmx_signal(SIGINT);
}
#ifdef HAVE_SIGUSR1
if (getenv("GMX_NO_USR1") == NULL)
{
fprintf(debug,"Installing signal handler for SIGUSR1\n");
}
- signal(SIGUSR1,signal_handler);
+ gmx_signal(SIGUSR1);
}
#endif
}
bStop=FALSE;
for(k=0; (k<4) && !bStop; k++) {
ai[k] = search_atom(idihs->b[j].a[k],start,
- atoms->nr,atoms->atom,atoms->atomname,
+ atoms,
"improper",bAllowMissing);
if (ai[k] == NO_ATID)
bStop = TRUE;
for(e=0; e<hbexcl->nb; e++) {
anm = hbexcl->b[e].a[0];
- i1 = search_atom(anm,astart,atoms->nr,atoms->atom,atoms->atomname,
+ i1 = search_atom(anm,astart,atoms,
"exclusion",bAllowMissing);
anm = hbexcl->b[e].a[1];
- i2 = search_atom(anm,astart,atoms->nr,atoms->atom,atoms->atomname,
+ i2 = search_atom(anm,astart,atoms,
"exclusion",bAllowMissing);
if (i1!=NO_ATID && i2!=NO_ATID) {
if (i1 > i2) {
for(i=0; (i<pdba->nr) && (pdba->atom[i].resind != resind); i++)
;
- return search_atom(name,i,pdba->nr,pdba->atom,pdba->atomname,
+ return search_atom(name,i,pdba,
searchtype,bAllowMissing);
}
}
static atom_id search_res_atom(const char *type,int resind,
- int natom,t_atom at[],
- char ** const *aname,
+ t_atoms *atoms,
const char *bondtype,gmx_bool bAllowMissing)
{
int i;
- for(i=0; (i<natom); i++)
- if (at[i].resind == resind)
- return search_atom(type,i,natom,at,aname,bondtype,bAllowMissing);
+ for(i=0; (i<atoms->nr); i++)
+ {
+ if (atoms->atom[i].resind == resind)
+ {
+ return search_atom(type,i,atoms,bondtype,bAllowMissing);
+ }
+ }
return NO_ATID;
}
-static void do_ssbonds(t_params *ps,int natoms,t_atom atom[],char **aname[],
+static void do_ssbonds(t_params *ps,t_atoms *atoms,
int nssbonds,t_ssbond *ssbonds,gmx_bool bAllowMissing)
{
int i,ri,rj;
for(i=0; (i<nssbonds); i++) {
ri = ssbonds[i].res1;
rj = ssbonds[i].res2;
- ai = search_res_atom(ssbonds[i].a1,ri,natoms,atom,aname,
+ ai = search_res_atom(ssbonds[i].a1,ri,atoms,
"special bond",bAllowMissing);
- aj = search_res_atom(ssbonds[i].a2,rj,natoms,atom,aname,
+ aj = search_res_atom(ssbonds[i].a2,rj,atoms,
"special bond",bAllowMissing);
if ((ai == NO_ATID) || (aj == NO_ATID))
gmx_fatal(FARGS,"Trying to make impossible special bond (%s-%s)!",
}
static void at2bonds(t_params *psb, t_hackblock *hb,
- int natoms, t_atom atom[], char **aname[],
- int nres, rvec x[],
+ t_atoms *atoms,
+ rvec x[],
real long_bond_dist, real short_bond_dist,
gmx_bool bAllowMissing)
{
fprintf(stderr,"Making bonds...\n");
i=0;
- for(resind=0; (resind < nres) && (i<natoms); resind++) {
+ for(resind=0; (resind < atoms->nres) && (i<atoms->nr); resind++) {
/* add bonds from list of bonded interactions */
for(j=0; j < hb[resind].rb[ebtsBONDS].nb; j++) {
/* Unfortunately we can not issue errors or warnings
* for missing atoms in bonds, as the hydrogens and terminal atoms
* have not been added yet.
*/
- ai=search_atom(hb[resind].rb[ebtsBONDS].b[j].AI,i,natoms,atom,aname,
+ ai=search_atom(hb[resind].rb[ebtsBONDS].b[j].AI,i,atoms,
ptr,TRUE);
- aj=search_atom(hb[resind].rb[ebtsBONDS].b[j].AJ,i,natoms,atom,aname,
+ aj=search_atom(hb[resind].rb[ebtsBONDS].b[j].AJ,i,atoms,
ptr,TRUE);
if (ai != NO_ATID && aj != NO_ATID) {
dist2 = distance2(x[ai],x[aj]);
}
}
/* add bonds from list of hacks (each added atom gets a bond) */
- while( (i<natoms) && (atom[i].resind == resind) ) {
+ while( (i<atoms->nr) && (atoms->atom[i].resind == resind) ) {
for(j=0; j < hb[resind].nhack; j++)
if ( ( hb[resind].hack[j].tp > 0 ||
hb[resind].hack[j].oname==NULL ) &&
- strcmp(hb[resind].hack[j].AI,*(aname[i])) == 0 ) {
+ strcmp(hb[resind].hack[j].AI,*(atoms->atomname[i])) == 0 ) {
switch(hb[resind].hack[j].tp) {
case 9: /* COOH terminus */
add_param(psb,i,i+1,NULL,NULL); /* C-O */
{
int residx,i,j,k;
const char *ptr;
- int natoms = atoms->nr;
- t_atom *atom = atoms->atom;
- char ***aname = atoms->atomname;
t_resinfo *resinfo = atoms->resinfo;
int nres = atoms->nres;
gmx_bool bAddCMAP;
for(k = 0; k < NUM_CMAP_ATOMS && bAddCMAP; k++)
{
cmap_atomid[k] = search_atom(restp[residx].rb[ebtsCMAP].b[j].a[k],
- i,natoms,atom,aname,ptr,TRUE);
+ i,atoms,ptr,TRUE);
bAddCMAP = bAddCMAP && (cmap_atomid[k] != NO_ATID);
if (!bAddCMAP)
{
* into the atom array. */
break;
}
- this_residue_index = atom[cmap_atomid[k]].resind;
+ this_residue_index = atoms->atom[cmap_atomid[k]].resind;
if (0 == k)
{
cmap_chainnum = resinfo[this_residue_index].chainnum;
if(residx<nres-1)
{
- while(atom[i].resind<residx+1)
+ while(atoms->atom[i].resind<residx+1)
{
i++;
}
/* Make bonds */
at2bonds(&(plist[F_BONDS]), hb,
- atoms->nr, atoms->atom, atoms->atomname, atoms->nres, *x,
+ atoms, *x,
long_bond_dist, short_bond_dist, bAllowMissing);
/* specbonds: disulphide bonds & heme-his */
do_ssbonds(&(plist[F_BONDS]),
- atoms->nr, atoms->atom, atoms->atomname, nssbonds, ssbonds,
+ atoms, nssbonds, ssbonds,
bAllowMissing);
nmissat = name2type(atoms, &cgnr, atype, restp, rt);
#define BUFSIZE 1024
static void atom_not_found(int fatal_errno,const char *file,int line,
const char *atomname,int resind,
+ const char *resname,
const char *bondtype,gmx_bool bAllowMissing)
{
char message_buffer[BUFSIZE];
if (0 != strcmp(bondtype, "atom"))
{
snprintf(message_buffer, 1024,
- "Atom %s is used in an interaction of type %s in the topology\n"
- "database, but an atom of that name was not found in residue\n"
- "number %d.\n",
- atomname,bondtype,resind+1);
+ "Residue %d named %s of a molecule in the input file was mapped\n"
+ "to an entry in the topology database, but the atom %s used in\n"
+ "an interaction of type %s in that entry is not found in the\n"
+ "input file. Perhaps your atom and/or residue naming needs to be\n"
+ "fixed.\n",
+ resind+1, resname, atomname, bondtype);
}
else
{
snprintf(message_buffer, 1024,
- "Atom %s is used in the topology database, but an atom of that\n"
- "name was not found in residue number %d.\n",
- atomname,resind+1);
+ "Residue %d named %s of a molecule in the input file was mapped\n"
+ "to an entry in the topology database, but the atom %s used in\n"
+ "that entry is not found in the input file. Perhaps your atom\n"
+ "and/or residue naming needs to be fixed.\n",
+ resind+1, resname, atomname);
}
if (bAllowMissing)
{
}
}
-atom_id search_atom(const char *type,int start,int natoms,t_atom at[],
- char ** const * anm,
+atom_id search_atom(const char *type,int start,
+ t_atoms *atoms,
const char *bondtype,gmx_bool bAllowMissing)
{
int i,resind=-1;
gmx_bool bPrevious,bNext;
+ int natoms = atoms->nr;
+ t_atom *at = atoms->atom;
+ char ** const * anm = atoms->atomname;
bPrevious = (strchr(type,'-') != NULL);
bNext = (strchr(type,'+') != NULL);
return (atom_id) i;
}
if (!(bNext && at[start].resind==at[natoms-1].resind))
- atom_not_found(FARGS,type,at[start].resind,bondtype,bAllowMissing);
+ {
+ atom_not_found(FARGS,type,at[start].resind,*atoms->resinfo[resind].name,bondtype,bAllowMissing);
+ }
}
else {
/* The previous residue */
if (gmx_strcasecmp(type,*(anm[i]))==0)
return (atom_id) i;
if (start > 0)
- atom_not_found(FARGS,type,at[start].resind,bondtype,bAllowMissing);
+ {
+ atom_not_found(FARGS,type,at[start].resind,*atoms->resinfo[resind].name,bondtype,bAllowMissing);
+ }
}
return NO_ATID;
}
#include "typedefs.h"
extern atom_id search_atom(const char *type,int start,
- int natoms,t_atom at[],
- char ** const * anm,
+ t_atoms *atoms,
const char *bondtype,gmx_bool bAllowMissing);
/* Search an atom in array of pointers to strings, starting from start
* if type starts with '-' then searches backwards from start.
}
}
}
+ teller++;
}
} while (bCont && (timecheck == 0));
"which should contain exactly one atom. In this case, only hydrogen",
"bonds between atoms within the shell distance from the one atom are",
"considered.[PAR]",
+
+ "With option -ac, rate constants for hydrogen bonding can be derived with the model of Luzar and Chandler",
+ "(Nature 394, 1996; J. Chem. Phys. 113:23, 2000) or that of Markovitz and Agmon (J. Chem. Phys 129, 2008).",
+ "If contact kinetics are analyzed by using the -contact option, then",
+ "n(t) can be defined as either all pairs that are not within contact distance r at time t",
+ "(corresponding to leaving the -r2 option at the default value 0) or all pairs that",
+ "are within distance r2 (corresponding to setting a second cut-off value with option -r2).",
+ "See mentioned literature for more details and definitions."
+ "[PAR]",
/* "It is also possible to analyse specific hydrogen bonds with",
"[TT]-sel[tt]. This index file must contain a group of atom triplets",
for(m=DIM-1; m>=0; m--)
{
+ if (hbox[m] == 0)
+ {
+ continue;
+ }
while(xcur[ind][m]-xprev[ind][m] <= -hbox[m])
rvec_inc(xcur[ind],box[m]);
while(xcur[ind][m]-xprev[ind][m] > hbox[m])