Commit 6ccf6169 authored by Peter Eastman's avatar Peter Eastman
Browse files

Removed Brook platform

parent 82e0bd2f
......@@ -329,11 +329,6 @@ MARK_AS_ADVANCED(CUDA_VERBOSE_BUILD)
MARK_AS_ADVANCED(CUDA_BUILD_CUBIN)
MARK_AS_ADVANCED(CUDA_BUILD_EMULATION)
SET(OPENMM_BUILD_BROOK_LIB OFF CACHE BOOL "Build OpenMMBrook library for ATI GPUs")
IF(OPENMM_BUILD_BROOK_LIB)
ADD_SUBDIRECTORY(platforms/brook)
ENDIF(OPENMM_BUILD_BROOK_LIB)
IF(NOT cmv EQUAL "2.4")
FIND_PACKAGE(OpenCL QUIET)
ENDIF(NOT cmv EQUAL "2.4")
......
#----------------------------------------------------
# OpenMM Brook Platform
#
# Creates OpenMM library, base name=OpenMM_Brook.
# Default libraries are shared & optimized. Variants
# are created for static (_static) and debug (_d).
#
# Windows:
# OpenMM_Brook[_d].dll
# OpenMM_Brook[_d].lib
# OpenMM_BROOK_static[_d].lib
# Unix:
# libOpenMM_Brook[_d].so
# libOpenMM_BROOK_static[_d].a
#----------------------------------------------------
SUBDIRS (tests)
# include static brook
SET(INCLUDE_BROOK_STATIC 1)
# logging
SET(LOG TRUE)
IF(LOG)
SET(LOG_FILE "CMakeLog.txt" )
FILE( WRITE ${LOG_FILE} "In Brook Cmake\n")
ENDIF(LOG)
# ----------------------------------------------------------------------------
IF(LOG)
MACRO(LOG_DIR LOG_FILE DIR_LIST DIRS1 )
FILE( APPEND ${LOG_FILE} "\n${DIR_LIST}\n")
FOREACH(currentFile ${ARGN})
FILE( APPEND ${LOG_FILE} " ${currentFile}\n" )
ENDFOREACH(currentFile)
ENDMACRO(LOG_DIR)
LOG_DIR( ${LOG_FILE} "API_INCLUDE_DIRS" ${API_INCLUDE_DIRS} )
ENDIF(LOG)
# ----------------------------------------------------------------------------
# The source is organized into subdirectories, but we handle them all from
# this CMakeLists file rather than letting CMake visit them as SUBDIRS.
SET(OPENMM_SOURCE_SUBDIRS .)
# Collect up information about the version of the OpenMM library we're building
# and make it available to the code so it can be built into the binaries.
SET(OpenMM_BROOK_LIBRARY_NAME OpenMM_Brook)
SET(SHARED_BROOK_TARGET ${OpenMM_BROOK_LIBRARY_NAME})
SET(STATIC_BROOK_TARGET ${OpenMM_BROOK_LIBRARY_NAME}_static)
# Ensure that debug libraries have "_d" appended to their names.
# CMake gets this right on Windows automatically with this definition.
IF (${CMAKE_GENERATOR} MATCHES "Visual Studio")
SET(CMAKE_DEBUG_POSTFIX "_d" CACHE INTERNAL "" FORCE)
ENDIF (${CMAKE_GENERATOR} MATCHES "Visual Studio")
# But on Unix or Cygwin we have to add the suffix manually
IF (UNIX AND CMAKE_BUILD_TYPE MATCHES Debug)
SET(SHARED_BROOK_TARGET ${SHARED_BROOK_TARGET}_d)
SET(STATIC_BROOK_TARGET ${STATIC_BROOK_TARGET}_d)
ENDIF (UNIX AND CMAKE_BUILD_TYPE MATCHES Debug)
# These are all the places to search for header files which are
# to be part of the API.
SET(API_INCLUDE_DIRS) # start empty
FOREACH(subdir ${OPENMM_SOURCE_SUBDIRS})
# append
SET(API_INCLUDE_DIRS ${API_INCLUDE_DIRS}
${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/include
${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/include/internal)
ENDFOREACH(subdir)
# We'll need both *relative* path names, starting with their API_INCLUDE_DIRS,
# and absolute pathnames.
SET(API_REL_INCLUDE_FILES) # start these out empty
SET(API_ABS_INCLUDE_FILES)
FOREACH(dir ${API_INCLUDE_DIRS})
FILE(GLOB fullpaths ${dir}/*.h) # returns full pathnames
SET(API_ABS_INCLUDE_FILES ${API_ABS_INCLUDE_FILES} ${fullpaths})
FOREACH(pathname ${fullpaths})
GET_FILENAME_COMPONENT(filename ${pathname} NAME)
SET(API_REL_INCLUDE_FILES ${API_REL_INCLUDE_FILES} ${dir}/${filename})
ENDFOREACH(pathname)
ENDFOREACH(dir)
# ----------------------------------------------------------------------------
IF(LOG)
LOG_DIR( ${LOG_FILE} "API_ABS_INCLUDE_FILES" ${API_ABS_INCLUDE_FILES} )
LOG_DIR( ${LOG_FILE} "API_REL_INCLUDE_FILES" ${API_REL_INCLUDE_FILES} )
LOG_DIR( ${LOG_FILE} "CMAKE_CURRENT_SOURCE_DIR" ${CMAKE_CURRENT_SOURCE_DIR} )
ENDIF(LOG)
# ----------------------------------------------------------------------------
# collect cpp source files
SET(SOURCE_FILES) # empty
SET(SOURCE_INCLUDE_FILES)
# SET( CMAKE_CURRENT_SOURCE_DIR /home/friedrim/src/openmm/trunk/OpenMM/platforms/brook )
FOREACH(subdir ${OPENMM_SOURCE_SUBDIRS})
FILE(GLOB src_files ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/src/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/src/*/*.cpp)
FILE(GLOB incl_files ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/src/*.h)
SET(SOURCE_FILES ${SOURCE_FILES} ${src_files}) #append
SET(SOURCE_INCLUDE_FILES ${SOURCE_INCLUDE_FILES} ${incl_files})
INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/include)
ENDFOREACH(subdir)
INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/src)
# ----------------------------------------------------------------------------
IF(LOG)
LOG_DIR( ${LOG_FILE} "BROOK_SOURCE_FILES" ${SOURCE_FILES} )
LOG_DIR( ${LOG_FILE} "SOURCE_INCLUDE_FILES" ${SOURCE_INCLUDE_FILES} )
ENDIF(LOG)
# ----------------------------------------------------------------------------
# Brook setup
# MESSAGE("CMAKE_CURRENT_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}" )
INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/brook-cmake/FindBrook.cmake)
INCLUDE_DIRECTORIES(${BROOK_INCLUDE_DIR})
LINK_DIRECTORIES(${${BROOK_brook_LIBRARY}})
# get *br files
FILE(GLOB BROOK_SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/kernels/*.br)
FILE(GLOB BROOK_INCLUDE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/kernels/*.h)
FILE( APPEND ${LOG_FILE} "BROOK_SRC_FILES=${BROOK_SRC_FILES}\n" )
# ----------------------------------------------------------------------------
IF(LOG)
# LOG_DIR( ${LOG_FILE} "Brook src" ${BROOK_SRC_FILES} )
# LOG_DIR( ${LOG_FILE} "Brook include" ${BROOK_INCLUDE_FILES} )
ENDIF(LOG)
# ----------------------------------------------------------------------------
# create Brook custom rules
SET(BROOK_CPP_FILES)
FOREACH(brookFile ${BROOK_SRC_FILES})
BROOK_FILE( ${brookFile} )
ENDFOREACH(brookFile)
# ----------------------------------------------------------------------------
IF(LOG)
# LOG_DIR( ${LOG_FILE} "Brook cpp" ${BROOK_CPP_FILES} )
ENDIF(LOG)
# ----------------------------------------------------------------------------
# BROOK_INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/src)
ADD_LIBRARY(${SHARED_BROOK_TARGET} SHARED ${BROOK_CPP_FILES} ${SOURCE_FILES} ${SOURCE_INCLUDE_FILES} )
SET_TARGET_PROPERTIES(${SHARED_BROOK_TARGET} PROPERTIES COMPILE_FLAGS "-DOPENMM_BUILDING_SHARED_LIBRARY")
IF(INCLUDE_BROOK_STATIC)
SET( BROOK_STATIC_COMPILE_FLAG "-DOPENMM_BUILDING_STATIC_LIBRARY -DOPENMM_USE_STATIC_LIBRARIES")
ADD_LIBRARY(${STATIC_BROOK_TARGET} STATIC ${BROOK_CPP_FILES} ${SOURCE_FILES} ${SOURCE_INCLUDE_FILES} )
SET_TARGET_PROPERTIES(${STATIC_BROOK_TARGET} PROPERTIES COMPILE_FLAGS ${BROOK_STATIC_COMPILE_FLAG})
ENDIF(INCLUDE_BROOK_STATIC)
# ----------------------------------------------------------------------------
IF(LOG)
FILE( APPEND ${LOG_FILE} "\nSTATIC_BROOK_TARGET=${STATIC_BROOK_TARGET} OPENMM_LIBRARY_NAME=${OPENMM_LIBRARY_NAME}\n" )
FILE( APPEND ${LOG_FILE} "SHARED_BROOK_TARGET=${SHARED_BROOK_TARGET} SHARED_TARGET=${SHARED_TARGET} STATIC_TARGET=${STATIC_TARGET}\n" )
FILE( APPEND ${LOG_FILE} "PROJECT_BINARY_DIR=${PROJECT_BINARY_DIR} BROOK_LIB_PATH=${BROOK_LIB_PATH}\n" )
ENDIF(LOG)
# ----------------------------------------------------------------------------
# shared
# TARGET_LINK_LIBRARIES(${SHARED_BROOK_TARGET} debug ${OPENMM_LIBRARY_NAME}_d optimized ${OPENMM_LIBRARY_NAME})
TARGET_LINK_LIBRARIES(${SHARED_BROOK_TARGET} ${SHARED_TARGET})
# the line below does not work for some reason
# using the following 3 lines in its place until understand more fully source of problem
# TARGET_LINK_LIBRARIES(${SHARED_BROOK_TARGET} debug brook_d optimized brook)
SET(BrookLib ${BROOK_LIB_PATH}/brook.lib)
SET(BrookDebugLib ${BROOK_LIB_PATH}/brook_d.lib)
TARGET_LINK_LIBRARIES(${SHARED_BROOK_TARGET} debug ${BrookDebugLib} optimized ${BrookLib})
LINK_DIRECTORIES(${SHARED_BROOK_TARGET} ${BROOK_LIB_PATH})
LINK_DIRECTORIES(${SHARED_BROOK_TARGET} ${PROJECT_BINARY_DIR})
# ----------------------------------------------------------------------------
#static
IF(INCLUDE_BROOK_STATIC)
TARGET_LINK_LIBRARIES(${STATIC_BROOK_TARGET} debug ${OPENMM_LIBRARY_NAME}_static_d optimized ${OPENMM_LIBRARY_NAME}_static)
TARGET_LINK_LIBRARIES(${STATIC_BROOK_TARGET} debug brook_d optimized brook)
TARGET_LINK_LIBRARIES(${STATIC_BROOK_TARGET} ${STATIC_TARGET})
LINK_DIRECTORIES(${STATIC_BROOK_TARGET} ${BROOK_LIB_PATH})
ENDIF(INCLUDE_BROOK_STATIC)
# ----------------------------------------------------------------------------
#install
IF(INCLUDE_BROOK_STATIC)
INSTALL_TARGETS(/lib/plugins RUNTIME_DIRECTORY /lib/plugins ${STATIC_BROOK_TARGET})
ENDIF(INCLUDE_BROOK_STATIC)
INSTALL_TARGETS(/lib/plugins RUNTIME_DIRECTORY /lib/plugins ${SHARED_BROOK_TARGET})
# - Look for the BrookGPU streaming extension to C language
#
# BROOK_FILE : .BR -> .CPP
# BROOK_INCLUDE_DIR : Include directory for Brook.hpp
# BROOK_C[XX]FLAGS : Flags needed to compile the produced CPP file
# BROOK_LIBRARIES : All needed libraries, including OpenGL for OGL backend
#
# Used internally :
# BROOK_CC : Location of BRCC
# BROOK_xxx_LIBRARY : Location of the various libraries used by brook
#
# ----------------------------------------------------------------------------
# Call find twice, so BROOKROOT takes precedence, but system path is a fallback
FIND_PATH(BROOK_INCLUDE_DIR brook/brook.hpp $ENV{BROOKROOT}/sdk/include NO_DEFAULT_PATH)
FIND_PATH(BROOK_INCLUDE_DIR brook/brook.hpp)
SET(BROOK_CXXFLAGS "-I${BROOK_INCLUDE_DIR}")
SET(BROOK_CFLAGS "${BROOK_CXXFLAGS}")
# Call find twice, so BROOKROOT takes precedence, but system path is a fallback
FIND_PROGRAM(BROOK_CC brcc $ENV{BROOKROOT}/sdk/bin NO_DEFAULT_PATH)
FIND_PROGRAM(BROOK_CC brcc)
# Search for all libraries
# - both BASE and RUNTIME TARGETS
# ----------------------------------------------------------------------------
FIND_LIBRARY(BROOK_brook_LIBRARY
NAMES
brook
brook_d
PATHS
$ENV{BROOKROOT}/sdk/lib)
# if found, add to list
IF (BROOK_brook_LIBRARY)
SET(BROOK_LIBRARIES ${BROOK_LIBRARIES} ${BROOK_brook_LIBRARY})
ENDIF (BROOK_brook_LIBRARY)
# all individual libs are advanced settings
MARK_AS_ADVANCED(BROOK_brook_LIBRARY)
# ----------------------------------------------------------------------------
IF(LOG)
FILE( APPEND ${LOG_FILE} "\nIn FindBrook.cmake\n" )
FILE( APPEND ${LOG_FILE} "BROOK_INCLUDE_DIR=${BROOK_INCLUDE_DIR}\n" )
FILE( APPEND ${LOG_FILE} "BROOK_CC=${BROOK_CC}\n" )
FILE( APPEND ${LOG_FILE} "BROOK_brook_LIBRARY=${BROOK_brook_LIBRARY}\n" )
FILE( APPEND ${LOG_FILE} "BROOKROOT=<$ENV{BROOKROOT}>\n" )
FILE( APPEND ${LOG_FILE} "sub_lib=<${sub_lib}>\n" )
ENDIF(LOG)
# ----------------------------------------------------------------------------
# check if includes and main lib are here
# IF (BROOK_INCLUDE_DIR AND BROOK_brook_LIBRARY AND BROOK_CC)
SET(BROOK_FOUND TRUE)
GET_FILENAME_COMPONENT(BROOK_LIB_PATH "${BROOK_brook_LIBRARY}" PATH)
# ----------------------------------------------------------------------------
IF(LOG)
FILE( APPEND ${LOG_FILE} "BROOK_LIB_PATH=${BROOK_LIB_PATH}\n" )
ENDIF(LOG)
# ----------------------------------------------------------------------------
# Implementation to allow interpreting/compiling Brook files
MACRO(BROOK_FILE FILENAME)
IF(LOG)
FILE( APPEND ${LOG_FILE} "1 In BROOK_FILE: ${FILENAME}\n" )
ENDIF(LOG)
# split input names
GET_FILENAME_COMPONENT(PATH "${FILENAME}" PATH)
GET_FILENAME_COMPONENT(HEAD "${FILENAME}" NAME_WE) # without trailing ".BR"
# File names
SET(OUTPATH "${CMAKE_CURRENT_BINARY_DIR}/src/kernels")
SET(BROOK_PREFIX "${OUTPATH}/${HEAD}")
SET(OUTFILE "${BROOK_PREFIX}.cpp") # file produced by Brook
# SET(INFILE "${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}") # canonical input name
SET(INFILE "${FILENAME}") # canonical input name
# ----------------------------------------------------------------------------
IF(LOG)
FILE( APPEND ${LOG_FILE} "In BROOK_FILE: ${FILENAME} FILENAME\n" )
FILE( APPEND ${LOG_FILE} " Path=${PATH} HEAD=${HEAD}\n" )
FILE( APPEND ${LOG_FILE} " OUTPATH=${OUTPATH}\n BROOK_PREFIX=${BROOK_PREFIX}\n" )
FILE( APPEND ${LOG_FILE} " OUTFILE=${OUTFILE}\n INFILE=${INFILE}\n\n" )
ENDIF(LOG)
# ----------------------------------------------------------------------------
# create output path, if it does not exist
IF(NOT EXISTS "${OUTPATH}")
FILE(MAKE_DIRECTORY "${OUTPATH}")
ENDIF(NOT EXISTS "${OUTPATH}")
# Run Brook
ADD_CUSTOM_COMMAND(
OUTPUT "${OUTFILE}"
COMMAND "${BROOK_CC}"
ARGS "-o${BROOK_PREFIX}"
"${INFILE}"
DEPENDS "${INFILE}" )
# Flag file as generated
SET_SOURCE_FILES_PROPERTIES("${OUTFILE}" PROPERTIES GENERATED TRUE)
# accumulate Brook cpp files
SET(BROOK_CPP_FILES ${BROOK_CPP_FILES} ${OUTFILE})
ENDMACRO(BROOK_FILE)
# ELSE (BROOK_INCLUDE_DIR AND BROOK_brook_LIBRARY AND BROOK_CC)
# SET(BROOK_FOUND FALSE)
#ENDIF (BROOK_INCLUDE_DIR AND BROOK_brook_LIBRARY AND BROOK_CC)
# Some verbosity
IF (NOT BROOK_FOUND)
IF (BROOK_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find BROOK" )
ENDIF (BROOK_FIND_REQUIRED)
ENDIF (NOT BROOK_FOUND)
# ----------------------------------------------------------------------------
IF(LOG)
FILE( APPEND ${LOG_FILE} "BROOK_FOUND=<${BROOK_FOUND}>\n" )
FILE( APPEND ${LOG_FILE} "\nLeaving FindBrook.cmake\n" )
ENDIF(LOG)
# ----------------------------------------------------------------------------
#ifndef OPENMM_BROOKKERNELFACTORY_H_
#define OPENMM_BROOKKERNELFACTORY_H_
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2008 Stanford University and the Authors. *
* Authors: Peter Eastman, Mark Friedrichs *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "openmm/KernelFactory.h"
namespace OpenMM {
/**
* This KernelFactory creates all kernels for BrookPlatform.
*/
class BrookKernelFactory : public KernelFactory {
public:
KernelImpl* createKernelImpl( std::string name, const Platform& platform, ContextImpl& context ) const;
};
} // namespace OpenMM
#endif /*OPENMM_BROOKKERNELFACTORY_H_*/
#ifndef OPENMM_BROOKPLATFORM_H_
#define OPENMM_BROOKPLATFORM_H_
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2008 Stanford University and the Authors. *
* Authors: Peter Eastman, Mark Friedrichs *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
// default float size for Brook
#define BrookOpenMMFloat float
#include "openmm/Platform.h"
#include "BrookStreamFactory.h"
namespace OpenMM {
class KernelImpl;
class OpenMMBrookInterface;
class BrookPlatformData {
public:
/**
* Constructor
*
*/
BrookPlatformData( void );
/**
* Destructor
*
*/
~BrookPlatformData( void );
/**
* Get _removeCOM flag
*
* @return _removeCOM
*
*/
int removeCOM( void ) const;
/**
* Get _useOBC flag
*
* @return _useOBC
*
*/
int useOBC( void ) const;
/**
* Get _hasBonds flag
*
* @return _hasBonds
*
*/
int hasBonds( void ) const;
/**
* Get _hasAngles
*
* @return _hasAngles
*
*/
int hasAngles( void ) const;
/**
* Get _hasPeriodicTorsions
*
* @return _hasPeriodicTorsions
*
*/
int hasPeriodicTorsions( void ) const;
/**
* Get _hasRB
*
* @return _hasRB
*
*/
int hasRB( void ) const;
/**
* Get _hasNonbonded
*
* @return _hasNonbonded
*
*/
int hasNonbonded( void ) const;
/**
* Get _cmMotionFrequency
*
* @return _cmMotionFrequency
*
*/
int cmMotionFrequency( void ) const;
private:
int _removeCOM;
int _useOBC;
int _hasBonds;
int _hasAngles;
int _hasPeriodicTorsions;
int _hasRB;
int _hasNonbonded;
int _cmMotionFrequency;
};
/**
* This Platform subclass uses the Brook implementations of all the OpenMM kernels.
*/
class OPENMM_EXPORT BrookPlatform : public Platform {
public:
// return values
static const int DefaultReturnValue = 0;
static const int DefaultErrorValue = -1;
/**
* BrookPlatform constructor
*
*/
BrookPlatform();
/**
* BrookPlatform constructor
*
* @param defaultParticleStreamWidth stream width
* @param runtime Brook runtime (cal/cpu)
* @param log log file reference
*
*/
BrookPlatform( int particleStreamWdith, const std::string& runtime, FILE* log = NULL );
/**
* BrookPlatform destructor
*
*/
~BrookPlatform();
/**
* Return platform name
*
* @return "Brook"
*/
const std::string& getName() const;
/**
* Return platform speed
*
* @return speed
*/
double getSpeed( void ) const;
/**
* Return true if BrookPlatform supports double precison
*
* @return true if BrookPlatform supports double precison
*/
// w/ FAH bool is redefined as int; causes problem w/ Platform::bool supportsDoublePrecision() const;
#define bool bool
bool supportsDoublePrecision( void ) const;
/**
* Return default Brook stream factory
*
* @return Brook stream factory
*/
const StreamFactory& getDefaultStreamFactory( void ) const;
/**
* Get the runtime
*
* @return runtime
*/
std::string getRuntime( void );
/**
* Get stream height and size given minimum number of elements in stream
*
* @param size input size of stream
* @param width width of stream
* @param height output height of stream (may be NULL)
*
* @return stream size (=streamWidth*height)
*/
static int getStreamSize( int size, int streamWidth, int* outputHeight );
/**
* Get default stream width
*
* @return default stream width
*/
int getParticleStreamWidth( void ) const;
/**
* Set log file reference
*
* @param log file reference
*
* @return DefaultReturnValue
*
*/
int setLog( FILE* log );
/*
* Get contents of object
*
* @param level of dump
*
* @return string containing contents
*
* */
std::string getContents( int level ) const;
/**
* Get log file reference
*
* @return log file reference
*
*/
FILE* getLog( void ) const;
/**
* This is called whenever a new Context is created. It gives the Platform a chance to initialize
* the context and store platform-specific data in it.
*/
void contextCreated( ContextImpl& context ) const;
/**
* This is called whenever a Context is deleted. It gives the Platform a chance to clean up
* any platform-specific data that was stored in it.
*/
void contextDestroyed( ContextImpl& context ) const;
/**
* Get minSuggestedThreads
*/
int getMinSuggestedThreads( void ) const;
/**
* Get duplicationFactor
*/
int getDuplicationFactor( int numberOfParticles ) const;
private:
// log file reference
FILE* _log;
// default stream factory
BrookStreamFactory _defaultStreamFactory;
// default stream width
static const int DefaultParticleStreamWidth = 32;
// particle streamwidth
int _particleStreamWidth;
// Brook runtime
std::string _runtime;
// min suggested threads
int _minSuggestedThreads;
/**
* Initialize kernel factory
*
*/
void _initializeKernelFactory( void );
/**
* Set & validate runtime
*
* @param runtime Brook runtime (cal/cpu)
*
* @throws exception if runtime is invalid
*/
void _setBrookRuntime( const std::string& runtime );
};
} // namespace OpenMM
#endif /*OPENMM_BROOKPLATFORM_H_*/
#ifndef OPENMM_BROOKSTREAMFACTORY_H_
#define OPENMM_BROOKSTREAMFACTORY_H_
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2008 Stanford University and the Authors. *
* Authors: Peter Eastman, Mark Friedrichs *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "openmm/StreamFactory.h"
#include "openmm/Platform.h"
namespace OpenMM {
/**
* This StreamFactory creates all streams for BrookPlatform.
*/
class OPENMM_EXPORT BrookStreamFactory : public StreamFactory {
public:
/**
* BrookStreamFactory constructor
*
*/
BrookStreamFactory( );
/**
* BrookStreamFactory destructor
*
*/
~BrookStreamFactory( );
// 'external' streams
static const std::string ParticlePositions;
static const std::string ParticleVelocities;
static const std::string ParticleForces;
/**
* Create StreamImpl
*
* @param name stream name
* @param size stream size
* @param type data type (float, float2, ...)
* @param platform platform reference
* @param context context (currently ignored)
*
* @return StreamImpl
*/
StreamImpl* createStreamImpl( std::string name, int size, Stream::DataType type, const Platform& platform, ContextImpl& context ) const;
/**
* Create StreamImpl
*
* @param name stream name
* @param size stream size
* @param type data type (float, float2, ...)
* @param platform platform reference
*
* @return StreamImpl
*/
StreamImpl* createStreamImpl( std::string name, int size, Stream::DataType type, const Platform& platform ) const;
/**
* Get particle stream width
*
* @return particle stream width
*
*
*/
int getDefaultParticleStreamWidth( void ) const;
/**
* Set particle stream width
*
* @param particleStreamWidth particle stream width
*
* @return DefaultReturnValue
*
* @throw OpenMMException if particleStreamWidth < 1
*
*/
int setDefaultParticleStreamWidth( int particleStreamWidth );
/**
* Get randomNumber stream width
*
* @return randomNumber stream width
*
*
*/
int getDefaultRandomNumberStreamWidth( void ) const;
/**
* Set randomNumber stream width
*
* @param randomNumberStreamWidth randomNumber stream width
*
* @return DefaultReturnValue
*
* @throw OpenMMException if randomNumberStreamWidth < 1
*
*/
int setDefaultRandomNumberStreamWidth( int randomNumberStreamWidth );
/**
* Get randomNumber stream size
*
* @return randomNumber stream size
*
*
*/
int getDefaultRandomNumberStreamSize( void ) const;
/**
* Set randomNumber stream size
*
* @param randomNumberStreamSize randomNumber stream size
*
* @return DefaultReturnValue
*
* @throw OpenMMException if randomNumberStreamSize < 1
*
*/
int setDefaultRandomNumberStreamSize( int randomNumberStreamSize );
/**
* Get default dangle value
*
* @return default dangle value
*
*/
double getDefaultDangleValue( void ) const;
/**
* Set default dangle value
*
* @param DefaultDangleValue default dangle value
*
* @return DefaultReturnValue
*
*/
int setDefaultDangleValue( double defaultDangleValue );
private:
static const int DefaultStreamParticleWidth = 32;
static const int DefaultStreamRandomNumberWidth = 1024;
static const int DefaultStreamRandomNumberSize = 1024*1024;
static const double DefaultDangleValue;
static const int DefaultReturnValue = 0;
static const int ErrorReturnValue = -1;
int _defaultParticleStreamWidth;
int _defaultStreamRandomNumberWidth;
int _defaultStreamRandomNumberSize;
double _defaultDangleValue;
};
} // namespace OpenMM
#endif /*OPENMM_BROOKSTREAMFACTORY_H_*/
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2009 Stanford University and the Authors. *
* Authors: Mark Friedrichs, Mike Houston *
* Contributors: *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as published *
* by the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* -------------------------------------------------------------------------- */
#include <sstream>
#include "BrookBondParameters.h"
#include "openmm/OpenMMException.h"
using namespace OpenMM;
using namespace std;
/**
* BrookBondParameters constructor
*
* @param bondName bond name
* @param numberOfParticlesInBond no. of particles in each bond
* @param numberOfParametersInBond no. of parameters in each bond
* @param numberOfBonds no. of bonds
* @param log optional log reference
*
*/
BrookBondParameters::BrookBondParameters( std::string bondName, int numberOfParticlesInBond,
int numberOfParametersInBond, int numberOfBonds, FILE* log = NULL ) :
_bondName( bondName ), _numberOfParticlesInBond( numberOfParticlesInBond ),
_numberOfParametersInBond( numberOfParametersInBond ), _numberOfBonds( numberOfBonds ), _log( log ){
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "BrookBondParameters::BrookBondParameters";
// ---------------------------------------------------------------------------------------
// allocate memory for particle indices/parameters
_bondParameters.resize( numberOfBonds );
_particleIndices.resize( numberOfBonds );
}
/**
* BrookBondParameters destructor
*
*/
BrookBondParameters::~BrookBondParameters( ){
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "BrookBondParameters::BrookBondParameters";
// ---------------------------------------------------------------------------------------
}
/**
* Get particle indices
*
* @return particle indices
*
*/
const std::vector<std::vector<int>>& BrookBondParameters::getParticleIndices( void ) const {
return _particleIndices;
}
/**
* Get bond parameters
*
* @return parameters
*
*/
const std::vector<std::vector<double>>& BrookBondParameters::getBondParameters( void ) const {
return _bondParameters;
}
/**
* Get log file reference
*
* @return log file reference
*
*/
FILE* BrookBondParameters::getLog( void ) const {
return _log;
}
/**
* Get bond name
*
* @return bond name
*
*/
std::string BrookBondParameters::getBondName( void ) const {
return _bondName;
}
/**
* Set log file reference
*
* @param log file reference
*
* @return DefaultReturnValue
*
*/
int BrookBondParameters::setLog( FILE* log ){
_log = log;
return DefaultReturnValue;
}
/**
* Get number of bonds
*
* @return numberOfBonds
*
*/
int BrookBondParameters::getNumberOfBonds( void ) const {
return _numberOfBonds;
}
/**
* Get number of particles in bond
*
* @return numberOfParticlesInBond
*
*/
int BrookBondParameters::getNumberOfParticlesInBond( void ) const {
return _numberOfParticlesInBond;
}
/**
* Get number of parameters in bond
*
* @return numberOfParametersInBond
*
*/
int BrookBondParameters::getNumberOfParametersInBond( void ) const {
return _numberOfParametersInBond;
}
/**
* Initialize the kernel, setting up the values of all the force field parameters.
*
* @param bondIndex bond index to be set
* @param particleIndices indices of particles (dimension=numberOfParticlesInBond)
* @param bondParameters bond parameters (dimension=numberOfParametersInBond)
*
* @return DefaultReturnValue
*
* @throw OpenMMException exeception if bond index is invalid
*
*/
int BrookBondParameters::setBond( int bondIndex, int* particleIndices, double* bondParameters ){
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookBondParameters::setBond";
FILE* log = getLog();
// ---------------------------------------------------------------------------------------
// validate bond index
if( bondIndex < 0 ){
std::stringstream message;
message << methodName << "BondIndex=" << bondIndex << " is < 0.";
throw OpenMMException( message.str() );
}
if( bondIndex >= getNumberOfBonds() ){
std::stringstream message;
message << methodName << "BondIndex=" << bondIndex << " is >= " << getNumberOfBonds() << ".";
throw OpenMMException( message.str() );
}
// load'em up
int numberOfParticlesInBond = getNumberOfParticlesInBond();
for( int ii = 0; ii < numberOfParticlesInBond; ii++ ){
_particleIndices[bondIndex].push_back( particleIndices[ii] );
}
int numberOfParametersInBond = getNumberOfParametersInBond();
for( int ii = 0; ii < numberOfParametersInBond; ii++ ){
//fprintf( stderr, "Param %s %d %e\n", getBondName().c_str(), ii, bondParameters[ii] );
_bondParameters[bondIndex].push_back( bondParameters[ii] );
}
// ---------------------------------------------------------------------------------------
return DefaultReturnValue;
}
/*
* Format line
*
* @param tab tab
* @param description description
* @param value value
*
* @return string containing contents
*
* */
std::string BrookBondParameters::_getLine( const std::string& tab,
const std::string& description,
const std::string& value ) const {
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookStreamInternal::_getLine";
static const unsigned int MAX_LINE_CHARS = 256;
char line[MAX_LINE_CHARS];
// ---------------------------------------------------------------------------------------
std::stringstream message;
memset( line, ' ', MAX_LINE_CHARS );
#ifdef _MSC_VER
(void) sprintf_s( line, MAX_LINE_CHARS, "%s %-40s %s", tab.c_str(), description.c_str(), value.c_str() );
#else
(void) sprintf( line, "%s %-40s %s", tab.c_str(), description.c_str(), value.c_str() );
#endif
message << std::string( line ) << std::endl;
return message.str();
}
/*
* Get contents of object
*
* @param level level of dump
*
* @return string containing contents
*
* */
std::string BrookBondParameters::getContentsString( int level ) const {
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookBondParameters::getContentsString";
static const unsigned int MAX_LINE_CHARS = 1024;
char value[MAX_LINE_CHARS];
static const char* Set = "Set";
static const char* NotSet = "Not set";
// ---------------------------------------------------------------------------------------
std::stringstream message;
std::string tab = " ";
#ifdef _MSC_VER
#define LOCAL_SPRINTF(a,b,c) sprintf_s( (a), MAX_LINE_CHARS, (b), (c) );
#define LOCAL_2_SPRINTF(a,b,c,d) sprintf_s( (a), MAX_LINE_CHARS, (b), (c), (d) );
#else
#define LOCAL_SPRINTF(a,b,c) sprintf( (a), (b), (c) );
#define LOCAL_2_SPRINTF(a,b,c,d) sprintf( (a), (b), (c), (d) );
#endif
(void) LOCAL_SPRINTF( value, "%s", getBondName().c_str() );
message << _getLine( tab, "Bond name:", value );
(void) LOCAL_SPRINTF( value, "%d", getNumberOfBonds() );
message << _getLine( tab, "Number of bonds:", value );
(void) LOCAL_SPRINTF( value, "%d", getNumberOfParticlesInBond() );
message << _getLine( tab, "Particles/bond:", value );
(void) LOCAL_SPRINTF( value, "%d", getNumberOfParametersInBond() );
message << _getLine( tab, "Parameters/bond:", value );
message << "Bonds:" << std::endl;
for( int ii = 0; ii < getNumberOfBonds(); ii++ ){
const static size_t descriptionSz = 1024;
char description[1024];
char buffer[1024];
(void) LOCAL_SPRINTF( description, "%6d [", ii );
#ifdef _MSC_VER
// particle indices
for( int jj = 0; jj < getNumberOfParticlesInBond(); jj++ ){
(void) LOCAL_SPRINTF( buffer, "%6d ", _particleIndices[ii][jj] );
(void) strcat_s( description, descriptionSz, buffer );
}
(void) strcat_s( description, descriptionSz, "] [" );
// parameters
for( int jj = 0; jj < getNumberOfParametersInBond(); jj++ ){
(void) LOCAL_SPRINTF( buffer, "%18.10e ", _bondParameters[ii][jj] );
(void) strcat_s( description, descriptionSz, buffer );
}
(void) strcat_s( description, descriptionSz, "]" );
#else
// particle indices
for( int jj = 0; jj < getNumberOfParticlesInBond(); jj++ ){
(void) LOCAL_SPRINTF( buffer, "%6d ", _particleIndices[ii][jj] );
(void) strcat( description, buffer );
}
(void) strcat( description, "] [" );
// parameters
for( int jj = 0; jj < getNumberOfParametersInBond(); jj++ ){
(void) LOCAL_SPRINTF( buffer, "%18.10e ", _bondParameters[ii][jj] );
(void) strcat( description, buffer );
}
(void) strcat( description, "]" );
#endif
message << _getLine( tab, "", description );
}
#undef LOCAL_SPRINTF
#undef LOCAL_2_SPRINTF
return message.str();
}
#ifndef OPENMM_BROOK_BOND_PARAMETERS_H_
#define OPENMM_BROOK_BOND_PARAMETERS_H_
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2009 Stanford University and the Authors. *
* Authors: Mark Friedrichs, Mike Houston *
* Contributors: *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as published *
* by the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* -------------------------------------------------------------------------- */
#include <vector>
namespace OpenMM {
/**
* Container for bond parameters
*/
class BrookBondParameters {
public:
// return values
static const int DefaultReturnValue = 0;
static const int ErrorReturnValue = -1;
/**
* BrookBondParameters constructor
*
* @param bondName bond name
* @param numberOfParticlesInBond no. of particles in each bond
* @param numberOfParametersInBond no. of parameters in each bond
* @param numberOfBonds no. of bonds
* @param log optional log reference
*
*/
BrookBondParameters( std::string bondName, int numberOfParticlesInBond, int numberOfParametersInBond, int numberOfBonds, FILE* log );
~BrookBondParameters();
/**
* Set log file reference
*
* @param log file reference
*
* @return DefaultReturnValue
*
*/
int setLog( FILE* log );
/*
* Get contents of object
*
* @param level of dump
*
* @return string containing contents
*
* */
std::string getContents( int level ) const;
/**
* Get log file reference
*
* @return log file reference
*
*/
FILE* getLog( void ) const;
/**
* Set bond info
*
* @param bondIndex index of bond
* @param particleIndices array of particle indices
* @param bondParameters array of bond parameters
*
* @return DefaultReturnValue
*
* @throw OpenMMException exeception if bond index is invalid
*
*/
int setBond( int bondIndex, int* particleIndices, double* bondParameters );
/**
* Get bond name
*
* @return bond name
*
*/
std::string getBondName( void ) const;
/**
* Set bond name
*
* @param bondName bond name
*
* @return DefaultReturnValue
*
*/
//int setBondName( std::string bondName );
/**
* Get NumberOfParticlesInBond
*
* @return NumberOfParticlesInBond
*
*/
int getNumberOfParticlesInBond( void ) const;
/**
* Get NumberOfParametersInBond
*
* @return NumberOfParametersInBond
*
*/
int getNumberOfParametersInBond( void ) const;
/**
* Get NumberOfBonds
*
* @return NumberOfBonds
*
*/
int getNumberOfBonds( void ) const;
/**
* Get particle indices
*
* @return particle indices
*
*/
const std::vector<std::vector<int>>& getParticleIndices( void ) const;
/**
* Get parameters
*
* @return parameters
*
*/
const std::vector<std::vector<double>>& getBondParameters( void ) const;
/*
* Get contents of object
*
*
* @param level level of dump
*
* @return string containing contents
*
* */
std::string getContentsString( int level = 0 ) const;
private:
// log file reference
FILE* _log;
// bond name
std::string _bondName;
// number of bonds
int _numberOfBonds;
int _numberOfParticlesInBond;
int _numberOfParametersInBond;
// particle indices and parameters
std::vector<std::vector<int>> _particleIndices;
std::vector<std::vector<double>> _bondParameters;
/*
* Get contents of object
*
* @param tab tab
* @param description description
* @param value value
*
* @return string containing contents
*
* */
std::string _getLine( const std::string& tab, const std::string& description,
const std::string& value ) const;
};
} // namespace OpenMM
#endif /* OPENMM_BROOK_BOND_PARAMETERS_H_ */
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2009 Stanford University and the Authors. *
* Authors: Mark Friedrichs, Mike Houston *
* Contributors: *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as published *
* by the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* -------------------------------------------------------------------------- */
#include "BrookBonded.h"
#include "BrookPlatform.h"
#include "BrookStreamFactory.h"
#include "openmm/OpenMMException.h"
#include "kernels/kinvmap_gather.h"
#include "kernels/invmap.h"
#include "kernels/kforce.h"
#include <cmath>
#include <sstream>
using namespace OpenMM;
using namespace std;
// 'defines' used to format paramater and atom index arrays
// carry over from original code
#define ATOMS(X,Y) (particles[ 5*(X) + (Y) + 1 ])
#define PARAMS(X,Y,Z) (params[(Y)][4*(X) + Z])
/**
*
* BrookBonded constructor
*
*/
BrookBonded::BrookBonded( ){
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookBonded::BrookBonded";
// ---------------------------------------------------------------------------------------
_setupCompleted = 0;
_numberOfParticles = 0;
_coulombFactor = static_cast<BrookOpenMMFloat>( 138.935485 );
_particleIndicesStream = NULL;
_chargeStream = NULL;
// parameter streams
for( int ii = 0; ii < getNumberOfParameterStreams(); ii++ ){
_bondedParameters[ii] = NULL;
}
// inverse maps & force streams
for( int ii = 0; ii < getNumberOfForceStreams(); ii++ ){
_bondedForceStreams[ii] = NULL;
_inverseMapStreamCount[ii] = 0;
for( int jj = 0; jj < MaxNumberOfInverseMaps; jj++ ){
_inverseStreamMaps[ii][jj] = NULL;
}
}
_maxInverseMapStreamCount[StreamI] = 9;
_maxInverseMapStreamCount[StreamJ] = 6;
_maxInverseMapStreamCount[StreamK] = 6;
_maxInverseMapStreamCount[StreamL] = 9;
_maxNumberOfInverseMaps = _maxInverseMapStreamCount[0];
for( int ii = 1; ii < getNumberOfForceStreams(); ii++ ){
if( _maxNumberOfInverseMaps < _maxInverseMapStreamCount[ii] ){
_maxNumberOfInverseMaps = _maxInverseMapStreamCount[ii];
}
}
// check that MaxNumberOfInverseMaps is big enough
if( _maxNumberOfInverseMaps > MaxNumberOfInverseMaps ){
std::stringstream message;
message << methodName << " max number of inverse maps=" << _maxNumberOfInverseMaps << " is greater than hardwired value=" << MaxNumberOfInverseMaps;
throw OpenMMException( message.str() );
}
_inverseMapStreamWidth = -1;
}
/**
* BrookBonded destructor
*
*/
BrookBonded::~BrookBonded( ){
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "BrookBonded::~BrookBonded";
// ---------------------------------------------------------------------------------------
delete _particleIndicesStream;
delete _chargeStream;
for( int ii = 0; ii < getNumberOfParameterStreams(); ii++ ){
delete _bondedParameters[ii];
}
for( int ii = 0; ii < getNumberOfForceStreams(); ii++ ){
delete _bondedForceStreams[ii];
for( int jj = 0; jj < MaxNumberOfInverseMaps; jj++ ){
delete _inverseStreamMaps[ii][jj];
}
}
}
/**
* Get number of parameter streams
*
* @return number of parameter streams
*
*/
int BrookBonded::getNumberOfParameterStreams( void ) const {
return NumberOfParameterStreams;
}
/**
* Get number of force streams
*
* @return number of force streams
*
*/
int BrookBonded::getNumberOfForceStreams( void ) const {
return NumberOfForceStreams;
}
/**
* Get max number of inverse maps
*
* @return max number of inverse maps
*
*/
int BrookBonded::getMaxInverseMapStreamCount( void ) const {
return _maxNumberOfInverseMaps;
}
/**
* Get max number of inverse maps for specified force stream index
*
* @param index index of force stream
*
* @return max number of inverse maps or -1 if index is out of range
*
*/
int BrookBonded::getMaxInverseMapStreamCount( int index ) const {
return (index >= 0 && index < getNumberOfForceStreams()) ? _maxInverseMapStreamCount[index] : -1;
}
/**
* Get width of inverse map streams
*
* @return width of inverse map streams
*
*/
int BrookBonded::getInverseMapStreamWidth( void ) const {
return _inverseMapStreamWidth;
}
/**
* Get Coulomb factor
*
* @return Coulomb factor
*
*/
BrookOpenMMFloat BrookBonded::getCoulombFactor( void ) const {
return _coulombFactor;
}
/**
* Return true if force[index] stream is set
*
* @param index into force stream
* @return true if index is valid && force[index] stream is set; else false
*
*/
int BrookBonded::isForceStreamSet( int index ) const {
return (index >= 0 && index < getNumberOfForceStreams() && _bondedForceStreams[index]) ? 1 : 0;
}
/**
* Return SetupCompleted flag
*
* @return SetupCompleted flag
*/
int BrookBonded::isSetupCompleted( void ) const {
return _setupCompleted;
}
/**
* Set SetupCompleted flag
*
* @param setupCompleted flag
*
* @return SetupCompleted flag
*/
int BrookBonded::setupCompleted( int setupCompleted ){
_setupCompleted = setupCompleted;
return _setupCompleted;
}
/**
* Return string showing if all inverse map streams are set
*
* @param index into inverse map stream array
*
* @return informative string
*
*/
std::string BrookBonded::checkInverseMapStream( int index ) const {
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookBonded::getContents";
int ok = 1;
// ---------------------------------------------------------------------------------------
std::stringstream message;
if( index < 0 || index >= getNumberOfForceStreams() ){
message << "Inverse map index=" << index << " is out of range [0, " << getNumberOfForceStreams() << ")";
return message.str();
}
message << "[ ";
for( int ii = 0; ii < getInverseMapStreamCount( index ); ii++ ){
message << (_inverseStreamMaps[index][ii] ? 1 : 0) << " ";
if( !_inverseStreamMaps[index][ii] ){
ok = 0;
}
}
message << " ]";
if( !ok ){
message << " ERROR!";
}
return message.str();
}
/**
* Return true if paramsterSet[index] stream is set
*
* @param index into parameter stream
*
* @return true if index is valid && paramsterSet[index] stream is set; else false
*
*/
int BrookBonded::isParameterStreamSet( int index ) const {
return (index >= 0 && index < getNumberOfParameterStreams() && _bondedParameters[index]) ? 1 : 0;
}
/**
* Validate stream count
*
* @return DefaultReturnValue if count valid; else return ErrorReturnValue
*
* @exception OpenMMException is thrown if count is invalid
*
*/
int BrookBonded::_validateInverseMapStreamCount( int index, int count ) const {
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookBonded::_validateInverseMapStreamCount";
// ---------------------------------------------------------------------------------------
int valid = DefaultReturnValue;
if( index == 2 ){
if( count > 5 ){
valid = ErrorReturnValue;
}
}
if( valid == ErrorReturnValue ){
std::stringstream message;
message << methodName << " input index=" << index << " has invalid count=" << count;
throw OpenMMException( message.str() );
}
return DefaultReturnValue;
}
/**
* Get inverse map stream count
*
* @return count
*
* @exception OpenMMException is thrown if index is out of range [0, getNumberOfForceStreams() ]
*
*/
int BrookBonded::getInverseMapStreamCount( int index ) const {
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookBonded::getInverseMapStreamCount";
// ---------------------------------------------------------------------------------------
if( index < 0 || index >= getNumberOfForceStreams() ){
std::stringstream message;
message << methodName << " input index=" << index << " is out of range [0, " << getNumberOfForceStreams() << " )";
throw OpenMMException( message.str() );
}
return _inverseMapStreamCount[index];
}
/**
* Get bonded particle indices stream
*
* @return particle indices stream
*
*/
BrookFloatStreamInternal* BrookBonded::getParticleIndicesStream( void ) const {
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "BrookBonded::getParticleIndicesStream";
// ---------------------------------------------------------------------------------------
return _particleIndicesStream;
}
/**
* Get bonded charge stream
*
* @return charge stream
*
*/
BrookFloatStreamInternal* BrookBonded::getChargeStream( void ) const {
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "BrookBonded::getChargeStream";
// ---------------------------------------------------------------------------------------
return _chargeStream;
}
/**
* Get array of bonded parameter streams
*
* @return array of bonded parameter streams
*
*/
BrookFloatStreamInternal** BrookBonded::getBondedParameterStreams( void ){
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "BrookBonded::getBondedParameterStreams";
// ---------------------------------------------------------------------------------------
return _bondedParameters;
}
/**
* Get array of force streams
*
* @return array force streams
*
*/
BrookFloatStreamInternal** BrookBonded::getBondedForceStreams( void ){
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "BrookBonded::getBondedForceStreams";
// ---------------------------------------------------------------------------------------
return _bondedForceStreams;
}
/**
* Get array of inverse map streams
*
* @param index array index
*
* @return array inverse map streams
*
*/
BrookFloatStreamInternal** BrookBonded::getInverseStreamMapsStreams( int index ){
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "BrookBonded::getInverseStreamMapsStreams";
// ---------------------------------------------------------------------------------------
// no checking on index -- assume ok -- speed
return _inverseStreamMaps[index];
}
/* Gromacs sorts most bonded interactions
* We sort those that gromacs forgets
* The parameters are all symmetric with respect
* to inversion of order.
*
* Also we assume that the same set of indices are not
* used with different sets of parameters in gromacs
* This is just an assumption for convenience here,
* nothing stops us from evaluating such terms in the
* kernel.
*
* To begin with all interactions have -1 -1 -1 -1
* After we fit in all the interactions, we have
* to convert the -1's to zeros to avoid indexing
* errors on the GPU.
* */
/*Flips i,j,k,l to l,k,j,i while correctly shuffling the params */
void BrookBonded::_flipQuartet( int ibonded, int *particles ){
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "BrookBonded::_flipQuartet";
// ---------------------------------------------------------------------------------------
int tmp;
//For now, simply flip the indices
//we're just studying the packing
// see 'defines' at top of file
tmp = ATOMS( ibonded, 0 );
ATOMS( ibonded, 0 ) = ATOMS( ibonded, 3 );
ATOMS( ibonded, 3 ) = ATOMS( ibonded, 0 );
tmp = ATOMS( ibonded, 1 );
ATOMS( ibonded, 1 ) = ATOMS( ibonded, 2 );
ATOMS( ibonded, 2 ) = ATOMS( ibonded, 1 );
}
int BrookBonded::_matchTorsion( int i, int j, int k, int l, int nbondeds, int *particles ){
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "BrookBonded::_matchTorsion";
// ---------------------------------------------------------------------------------------
int tmp;
if( j > k ){
//swap into order
tmp = i;
i = l;
l = tmp;
tmp = j;
j = k;
k = tmp;
}
for( int n = 0; n < nbondeds; n++ ){
if( i == ATOMS(n, 0) && j == ATOMS(n, 1) &&
k == ATOMS(n, 2) && l == ATOMS(n, 3) ){
return n;
}
}
return ErrorReturnValue;
}
/*
* We try to match i,j,k against the first 3 in a quartet, then
* against the next three. Then we check if there's a free slot
* in the fourth component and match the middle two components
*
* The last bit will not be needed as long as gromacs generates
* all torsions. But I think there are force fields that don't
* use all torsions.
*
* @return ErrorReturnValue if error; else particle index
*
**/
int BrookBonded::_matchAngle( int i, int j, int k, int nbondeds,
int *particles, int *flag ){
// ---------------------------------------------------------------------------------------
int n;
static const std::string methodName = "BrookBonded::_matchAngle";
// ---------------------------------------------------------------------------------------
// validate i > k
if( i > k ){
if( getLog() ){
(void) fprintf( getLog(), "%s Invalid triplet %d-%d-%d\n", methodName.c_str(), i, j, k );
(void) fflush( getLog() );
}
std::stringstream message;
message << methodName << " invalid triplet: " << i << "-" << j << "-" << k << std::endl;
throw OpenMMException( message.str() );
return ErrorReturnValue;
}
for( n = 0; n < nbondeds; n++ ){
if( j == ATOMS(n, 1) ){
if( (i == ATOMS(n, 0) && k == ATOMS(n, 2))
|| (i == ATOMS(n, 2) && k == ATOMS(n, 0)) ) {
*flag = 0;
return n;
}
}
else if( j == ATOMS(n, 2) ){
if( i == ATOMS(n, 1) ){
if( ATOMS(n, 3) == -1 || k == ATOMS(n, 3) ){
ATOMS(n, 3) = k;
*flag = 1;
return n;
}
}
else if( k == ATOMS(n, 1) ){
if( ATOMS(n, 3) == -1 || i == ATOMS(n, 3) ){
ATOMS(n, 3) = i;
*flag = 1;
return n;
}
}
}
}
return ErrorReturnValue;
}
/*
* flag = 0 means match i-j, 1 means j-k and 2 means k-l
* Again, like above, if we have uninitialized slots, we take em
*
* */
int BrookBonded::_matchBond( int i, int j, int nbondeds, int *particles, int *flag ){
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookBonded::_matchBond";
// ---------------------------------------------------------------------------------------
if( i > j ){
if( getLog() ){
(void) fprintf( getLog(), "%s invalid bond %d-%d\n", methodName.c_str(), i, j );
(void) fflush( getLog() );
}
std::stringstream message;
message << methodName << " invalid bond " << i << "-" << j << std::endl;
throw OpenMMException( message.str() );
return ErrorReturnValue;
}
for( int n = 0; n < nbondeds; n++ ){
if( ( i == ATOMS(n, 0) && j == ATOMS(n, 1) ) || ( i == ATOMS(n, 1) && j == ATOMS(n, 0) ) ){
*flag = 0;
return n;
}
//Try second spot
if( ATOMS(n, 2) == -1 ){ //One available spot
if( i == ATOMS(n, 1) ){
ATOMS(n, 2) = j;
*flag = 1;
return n;
}
if( j == ATOMS(n, 1) ){
ATOMS(n, 2) = i;
*flag = 1;
return n;
}
} else if( ( i == ATOMS(n, 1) && j == ATOMS(n, 2) ) ||( i == ATOMS(n, 2) && j == ATOMS(n, 1) ) ){
*flag = 1;
return n;
}
//Try third spot
if( ATOMS(n, 3) == -1 ){
if( i == ATOMS(n, 2) ){
ATOMS(n, 3) = j;
*flag = 2;
return n;
}
if( j == ATOMS(n, 2) ){
ATOMS(n, 3) = i;
*flag = 2;
return n;
}
} else if( ( i == ATOMS(n, 2) && j == ATOMS(n, 3) ) ||( i == ATOMS(n, 3) && j == ATOMS(n, 2) ) ){
*flag = 2;
return n;
}
}
return ErrorReturnValue;
}
int BrookBonded::_matchPair( int i, int j, int nbondeds, int *particles ){
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "BrookBonded::_matchPair";
// ---------------------------------------------------------------------------------------
for( int n = 0; n < nbondeds; n++ ){
//If there is an empty slot available:
if( ATOMS(n, 0) == -1 ){
//If one of i,j matches the l particle
if( ATOMS(n, 3) == i ){
ATOMS(n, 0) = j;
return n;
}
if( ATOMS(n, 3) == j ){
ATOMS(n, 0) = i;
return n;
}
}
//If the l-particle is available
if( ATOMS(n, 3) == -1 ){
if( ATOMS(n, 0) == i ){
ATOMS(n, 3) = j;
return n;
}
if( ATOMS(n, 0) == j ){
ATOMS(n, 3) = i;
return n;
}
}
//Both are unavailable, both much match
if( ( i == ATOMS(n, 0) && j == ATOMS(n, 3) )
|| ( i == ATOMS(n, 3) && j == ATOMS(n, 0) ) ){
return n;
}
}
return ErrorReturnValue;
}
/**
* Setup Ryckaert-Bellemans parameters/particle indices
*
* @param nbondeds number of bonded entries
* @param particles array of particle indices
* @param params arrays of bond parameters
* @param rbTorsionIndices the four particles connected by each Ryckaert-Bellemans torsion term
* @param rbTorsionParameters the coefficients (in order of increasing powers) for each Ryckaert-Bellemans torsion term
*
* @return nonzero value if error
*
*/
int BrookBonded::_addRBTorsions( int *nbondeds, int *particles, float *params[],
const vector<vector<int> >& rbTorsionIndices,
const vector<vector<double> >& rbTorsionParameters ){
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookBonded::_addRBTorsions";
static const int printOn = 0;
// ---------------------------------------------------------------------------------------
if( printOn && getLog() ){
(void) fprintf( getLog(), "%s number of bonds=%d\n", methodName.c_str(), rbTorsionIndices.size() );
}
for( unsigned int ii = 0; ii < rbTorsionIndices.size(); ii++ ){
vector<int> particlesIndices = rbTorsionIndices[ii];
vector<double> rbParameters = rbTorsionParameters[ii];
int index = 0;
int i = particlesIndices[index++];
int j = particlesIndices[index++];
int k = particlesIndices[index++];
int l = particlesIndices[index++];
int ibonded = _matchTorsion( i, j, k, l, *nbondeds, particles );
if( ibonded < 0 ){
ibonded = *nbondeds;
ATOMS( ibonded, 0 ) = i;
ATOMS( ibonded, 1 ) = j;
ATOMS( ibonded, 2 ) = k;
ATOMS( ibonded, 3 ) = l;
(*nbondeds)++;
}
// note -- we are starting w/ index c1 not c0 -- c0 is not used
// to calculate the forces!
index = 1;
PARAMS( ibonded, 0, 0 ) = static_cast<BrookOpenMMFloat>( rbParameters[index++] );
PARAMS( ibonded, 0, 1 ) = static_cast<BrookOpenMMFloat>( rbParameters[index++] );
PARAMS( ibonded, 0, 2 ) = static_cast<BrookOpenMMFloat>( rbParameters[index++] );
PARAMS( ibonded, 0, 3 ) = static_cast<BrookOpenMMFloat>( rbParameters[index++] );
PARAMS( ibonded, 1, 0 ) = static_cast<BrookOpenMMFloat>( rbParameters[index++] );
if( printOn && getLog() ){
(void) fprintf( getLog(), " %d [%d %d %d %d] %.3e %.3e %.3e %.3e\n", ibonded, i, j, k, l,
rbParameters[0], rbParameters[1],
rbParameters[2], rbParameters[3], rbParameters[4], rbParameters[5] );
}
}
return DefaultReturnValue;
}
/**
* Setup periodic torsion parameters/particle indices
*
* @param nbondeds number of bonded entries
* @param particles array of particle indices
* @param params arrays of bond parameters
* @param periodicTorsionIndices the four particles connected by each periodic torsion term
* @param periodicTorsionParameters the force parameters (k, phase, periodicity) for each periodic torsion term
*
* @return nonzero value if error
*
*/
int BrookBonded::_addPTorsions( int *nbondeds, int *particles, BrookOpenMMFloat* params[],
const vector<vector<int> >& periodicTorsionIndices,
const vector<vector<double> >& periodicTorsionParameters ){
// ---------------------------------------------------------------------------------------
static const BrookOpenMMFloat DEG2RAD = (BrookOpenMMFloat) (M_PI/180.0);
static const std::string methodName = "BrookBonded::_addPTorsion";
static const int printOn = 0;
// ---------------------------------------------------------------------------------------
FILE* log = getLog();
if( printOn ){
log = log ? log : stderr;
(void) fprintf( log, "%s npdih=%d\n", methodName.c_str(), periodicTorsionIndices.size() );
(void) fflush( log );
}
for( unsigned int ii = 0; ii < periodicTorsionIndices.size(); ii++ ){
vector<int> particlesIndices = periodicTorsionIndices[ii];
vector<double> pTParameters = periodicTorsionParameters[ii];
int index = 0;
int i = particlesIndices[index++];
int j = particlesIndices[index++];
int k = particlesIndices[index++];
int l = particlesIndices[index++];
int ibonded = _matchTorsion( i, j, k, l, *nbondeds, particles );
if( ibonded < 0 ){
ibonded = *nbondeds;
ATOMS( ibonded, 0 ) = i;
ATOMS( ibonded, 1 ) = j;
ATOMS( ibonded, 2 ) = k;
ATOMS( ibonded, 3 ) = l;
(*nbondeds)++;
}
// note: parameters 0 & 2 switched
PARAMS( ibonded, 1, 1 ) = static_cast<BrookOpenMMFloat>( pTParameters[2] );
PARAMS( ibonded, 1, 2 ) = static_cast<BrookOpenMMFloat>( pTParameters[1] );
PARAMS( ibonded, 1, 3 ) = static_cast<BrookOpenMMFloat>( pTParameters[0] );
if( printOn ){
(void) fprintf( log, " %d [%d %d %d %d] %.3e %.3e %.3e\n", ibonded, i, j, k, l,
pTParameters[0], pTParameters[1], pTParameters[2] );
(void) fflush( log );
}
}
return DefaultReturnValue;
}
/**
* Setup angle bond parameters/particle indices
*
* @param nbondeds number of bonded entries
* @param particles array of particle indices
* @param params arrays of bond parameters
* @param angleIndices the angle bond particle indices
* @param angleParameters the angle parameters (angle in radians, force constant)
*
* @return nonzero value if error
*
*/
int BrookBonded::_addAngles( int *nbondeds, int *particles, float *params[], const std::vector<std::vector<int> >& angleIndices,
const std::vector<std::vector<double> >& angleParameters ){
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookBonded::_addAngles";
static const int printOn = 0;
// ---------------------------------------------------------------------------------------
if( printOn && getLog() ){
(void) fprintf( getLog(), "%s nang=%d\n", methodName.c_str(), angleIndices.size() );
}
// loop over bonds
for( unsigned int ii = 0; ii < angleIndices.size(); ii++ ){
vector<int> particlesIndices = angleIndices[ii];
vector<double> angParameters = angleParameters[ii];
int index = 0;
int i = particlesIndices[index++];
int j = particlesIndices[index++];
int k = particlesIndices[index++];
int flag;
int ibonded = _matchAngle( i, j, k, *nbondeds, particles, &flag );
if( ibonded < 0 ){
ibonded = *nbondeds;
ATOMS( ibonded, 0 ) = i;
ATOMS( ibonded, 1 ) = j;
ATOMS( ibonded, 2 ) = k;
flag = 0;
(*nbondeds)++;
}
PARAMS( ibonded, 2, flag*2 ) = static_cast<BrookOpenMMFloat>( angParameters[0] );
PARAMS( ibonded, 2, flag*2 + 1 ) = static_cast<BrookOpenMMFloat>( angParameters[1] );
if( printOn && getLog() ){
(void) fprintf( getLog(), " %d [%d %d %d ] %.6e %.6e\n", ibonded, i, j, k,
angParameters[0], angParameters[1] );
}
}
return DefaultReturnValue;
}
/**
* Setup harmonic bond parameters/particle indices
*
* @param nbondeds number of bonded entries
* @param particles array of particle indices
* @param params arrays of bond parameters
* @param bondIndices two harmonic bond particle indices
* @param bondParameters the force parameters (distance, k)
*
* @return nonzero value if error
*
*/
int BrookBonded::_addBonds( int *nbondeds, int *particles, float *params[], const vector<vector<int> >& bondIndices,
const vector<vector<double> >& bondParameters ){
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookBonded::_addBonds";
static const int printOn = 0;
// ---------------------------------------------------------------------------------------
if( printOn && getLog() ){
(void) fprintf( getLog(), "%s nbonds=%d\n", methodName.c_str(), bondIndices.size() );
}
// loop over bonds
for( unsigned int ii = 0; ii < bondIndices.size(); ii++ ){
vector<int> particlesIndices = bondIndices[ii];
vector<double> bndParameters = bondParameters[ii];
int index = 0;
int i = particlesIndices[index++];
int j = particlesIndices[index++];
// insure i < j
if( i > j ){
int k = i;
i = j;
j = k;
}
int flag;
int ibonded = _matchBond( i, j, *nbondeds, particles, &flag );
int saveIbond = ibonded;
if( ibonded < 0 ){
ibonded = *nbondeds;
ATOMS( ibonded, 0 ) = i;
ATOMS( ibonded, 1 ) = j;
flag = 0;
(*nbondeds)++;
}
if( flag < 2 ){
PARAMS( ibonded, 3, flag*2 ) = static_cast<BrookOpenMMFloat>( bndParameters[0] );
PARAMS( ibonded, 3, flag*2 + 1 ) = static_cast<BrookOpenMMFloat>( bndParameters[1] );
} else {
PARAMS( ibonded, 4, 0 ) = static_cast<BrookOpenMMFloat>( bndParameters[0] );
PARAMS( ibonded, 4, 1 ) = static_cast<BrookOpenMMFloat>( bndParameters[1] );
}
if( printOn && getLog() ){
(void) fprintf( getLog(), " %d (%5d) [%6d %6d ] flag=%2d %.3e %.3e\n", ibonded, saveIbond, i, j, flag,
bndParameters[0], bndParameters[1] );
}
}
return DefaultReturnValue;
}
/**
* Setup LJ/Coulomb 1-4 parameters/particle indices
*
* @param nbondeds number of bonded entries
* @param particles array of particle indices
* @param params arrays of bond parameters
* @param charges array of charges
* @param bonded14Indices each element contains the indices of two particles whose nonbonded interactions should be reduced since
* they form a bonded 1-4 pair
* @param nonbondedParameters the nonbonded force parameters (charge, sigma, epsilon) for each particle
* @param log log reference
*
* @return nonzero value if error
*
*/
int BrookBonded::_addPairs( int *nbondeds, int *particles, BrookOpenMMFloat* params[],
BrookOpenMMFloat* charges,
const std::vector<std::vector<int> >& bonded14Indices,
const std::vector<std::vector<double> >& nonbondedParameters ){
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookBonded::_addPairs";
static const double oneSixth = 1.0/6.0;
static const int printOn = 0;
// ---------------------------------------------------------------------------------------
if( printOn && getLog() ){
(void) fprintf( getLog(), "%s npairs=%d sz=%u %u\n", methodName.c_str(), bonded14Indices.size(), bonded14Indices.size(), nonbondedParameters.size() ); fflush( getLog() );
}
for( unsigned int ii = 0; ii < bonded14Indices.size(); ii++ ){
int i = bonded14Indices[ii][0];
int j = bonded14Indices[ii][1];
int ibonded = _matchPair( i, j, *nbondeds, particles );
if( ibonded < 0 ){
ibonded = *nbondeds;
ATOMS(ibonded, 0) = i;
ATOMS(ibonded, 3) = j;
(*nbondeds)++;
}
vector<double> iParameters = nonbondedParameters[ii];
PARAMS( ibonded, 4, 2 ) = static_cast<BrookOpenMMFloat>( iParameters[1] );
PARAMS( ibonded, 4, 3 ) = static_cast<BrookOpenMMFloat>( (4.0*iParameters[2]) );
// a little wasteful, but ...
charges[ibonded] = (BrookOpenMMFloat) iParameters[0];
if( printOn ){
(void) fprintf( getLog(), " %d [%d %d ] %.3e %.3e q=%.4f\n", ibonded, i, j, iParameters[1], iParameters[2], charges[ibonded] );
}
}
return DefaultReturnValue;
}
/**
* Create and load inverse maps for bonded ixns
*
* @param nbondeds number of bonded entries
* @param nparticles number of particles
* @param particles arrays of particle indices (particles[numberOfBonds][4])
* @param platform BrookPlatform reference
* @param log log file reference (optional)
*
* @return nonzero value if error
*
*/
int BrookBonded::_loadInvMaps( int nbondeds, int nparticles, int *particles, int particleStreamWidth, int particleStreamSize ){
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookBonded::_loadInvMaps";
static int printOn = 0;
double dangleValue = 0.0;
FILE* log = NULL;
// ---------------------------------------------------------------------------------------
printOn = (printOn && getLog()) ? printOn : 0;
// get particle stream size
/*
const BrookStreamFactory& brookStreamFactory = dynamic_cast<const BrookStreamFactory&> (brookPlatform.getDefaultStreamFactory() );
int particleStreamWidth = brookStreamFactory.getDefaultParticleStreamWidth();
int particleStreamSize = brookPlatform.getStreamSize( getNumberOfParticles(), particleStreamWidth, NULL );
*/
_inverseMapStreamWidth = particleStreamWidth;
// ---------------------------------------------------------------------------------------
// allocate temp memory
float4** invmaps = new float4*[getMaxInverseMapStreamCount()];
float* block = new float[4*getMaxInverseMapStreamCount()*particleStreamSize];
//memset( block, 0, 4*getMaxInverseMapStreamCount()*particleStreamSize*sizeof( float ) );
float* blockPtr = block;
for( int ii = 0; ii < getMaxInverseMapStreamCount(); ii++ ){
invmaps[ii] = (float4*) blockPtr;
blockPtr += 4*particleStreamSize;
}
int* counts = new int[particleStreamSize];
// ---------------------------------------------------------------------------------------
// get inverse maps and load into streams
// create streams
// done independently from loading since for test cases some stream counts == 0, but kernels expect stream to
// have been created even though unused
// load streams -- initialize all streams even if unused since gather methods will still pick up
for( int ii = 0; ii < getNumberOfForceStreams(); ii++ ){
for( int jj = 0; jj < getMaxInverseMapStreamCount(ii); jj++ ){
_inverseStreamMaps[ii][jj] = new BrookFloatStreamInternal( BrookCommon::BondedInverseMapStreams, particleStreamSize,
particleStreamWidth, BrookStreamInternal::Float4, dangleValue );
}
}
if( printOn ){
log = getLog();
(void) fprintf( log, "%s force stream strms=%d nbondeds=%d max counts=[%d %d %d %d] strSz&Wd=%d %d\n", methodName.c_str(), getNumberOfForceStreams(),
nbondeds, getMaxInverseMapStreamCount(0), getMaxInverseMapStreamCount(1), getMaxInverseMapStreamCount(2), getMaxInverseMapStreamCount(3),
particleStreamSize, particleStreamWidth );
(void) fflush( log );
}
// load data
for( int ii = 0; ii < getNumberOfForceStreams(); ii++ ){
for( int jj = 0; jj < 4*getMaxInverseMapStreamCount()*particleStreamSize; jj++ ){
block[jj] = -1.0f;
}
//(void) fprintf( stderr, "%s _gpuCalcInvMap %d getInverseMapStreamCount=%d\n", methodName.c_str(), ii, getInverseMapStreamCount( ii ) ); (void) fflush( log );
_gpuCalcInvMap( ii, 4, nbondeds, nparticles, particles, getMaxInverseMapStreamCount( ii ), counts, invmaps, &(_inverseMapStreamCount[ii]) );
//_gpuPrintInvMaps( _inverseMapStreamCount[ii], nparticles, counts, invmaps, stderr );
_validateInverseMapStreamCount( ii, _inverseMapStreamCount[ii] );
for( int jj = 0; jj < _inverseMapStreamCount[ii]; jj++ ){
_inverseStreamMaps[ii][jj]->loadFromArray( invmaps[jj] );
if( printOn ){
FILE* log = stderr;
(void) fprintf( log, "%s inverseMap stream strms=%d count=%d index=%d %d InverseMapStreamCount[ii]=%d max=%d\n",
methodName.c_str(), getNumberOfForceStreams(), _inverseMapStreamCount[ii], ii, jj,
getInverseMapStreamCount( ii ), getMaxInverseMapStreamCount( ii ) );
for( int kk = 0; kk < particleStreamSize; kk++ ){
(void) fprintf( log, "%8d [ %.1f %.1f %.1f %.1f]\n", kk, invmaps[jj][kk].x, invmaps[jj][kk].y, invmaps[jj][kk].z, invmaps[jj][kk].w );
}
}
}
// for small systems, must all initialize inverse maps to negative values in order to
// keep invalid entries from being included in forces
if( _inverseMapStreamCount[ii] < getMaxInverseMapStreamCount( ii ) ){
for( int jj = 0; jj < 4*particleStreamSize; jj++ ){
block[jj] = -1.0f;
}
for( int jj = _inverseMapStreamCount[ii]; jj < getMaxInverseMapStreamCount( ii ); jj++ ){
_inverseStreamMaps[ii][jj]->loadFromArray( invmaps[0] );
}
}
}
// diagnostics
if( printOn ){
(void) fprintf( log, "%s done\n", methodName.c_str() );
(void) fflush( log );
}
// free memory
delete[] counts;
delete[] invmaps[0];
delete[] invmaps;
return DefaultReturnValue;
}
/*
* Setup for bonded ixns
*
* @param numberOfParticles number of particles
* @param bondIndices vector of vector of harmonic bond indices -- one entry each bond (2 particles )
* @param bondParameters vector of vector of harmonic bond parameters -- one entry each bond (2 parameters)
* @param angleIndices vector of vector of angle bond indices -- one entry each bond (3 particles )
* @param angleParameters vector of vector of angle bond parameters -- one entry each bond (2 parameters)
* @param periodicTorsionIndices vector of vector of periodicTorsionIndices bond indices -- one entry each bond (4 particles )
* @param periodicTorsionParameters vector of vector of periodicTorsionParameters bond parameters -- one entry each bond (3 parameters)
* @param rbTorsionIndices vector of vector of rb torsion bond indices -- one entry each bond (4 particles )
* @param rbTorsionParameters vector of vector of rb torsion bond parameters -- one entry each bond (5 parameters)
* @param bonded14Indices vector of vector of Lennard-Jones 14 particle indices -- one entry each bond (2 particles )
* @param nonbondedParameters vector of vector of Lennard-Jones 14 parameters -- one entry each bond (3 parameters)
* @param platform Brook platform reference
*
* @return always 1
*
* We go through the interactions in the following order
* torsions
* angles
* 14 interactions
* bonds
* For each new interaction, we try to fit it in with
* those already in. This may not necessarily result in
* the optimal fit, but should not be too bad.
* */
int BrookBonded::setup( int numberOfParticles,
BrookBondParameters* harmonicBondBrookBondParameters,
BrookBondParameters* harmonicAngleBrookBondParameters,
BrookBondParameters* periodicTorsionBrookBondParameters,
BrookBondParameters* rbTorsionBrookBondParameters,
BrookBondParameters* nonBonded14ForceParameters,
int particleStreamWidth, int particleStreamSize ){
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookBonded::setup";
static int printOn = 0;
double dangleValue = 0.0;
FILE* log;
// ---------------------------------------------------------------------------------------
//setLog( stderr );
printOn = (printOn && getLog()) ? printOn : 0;
if( printOn ){
log = getLog();
(void) fprintf( log, "%s particles=%d\n [%p %p %p %p %p] (bond, angle, pd, rb, 14)\n"
"StreamW=%d StreamSz=%d\n", methodName.c_str(), numberOfParticles, harmonicBondBrookBondParameters,
harmonicAngleBrookBondParameters,
periodicTorsionBrookBondParameters, rbTorsionBrookBondParameters, nonBonded14ForceParameters,
particleStreamWidth, particleStreamSize ); fflush( log );
}
_numberOfParticles = numberOfParticles;
// check that particle indices & parameters agree
// allocate temp memory
int maxBonds = 10*numberOfParticles;
int* particles = new int[5*maxBonds];
float* charges = new BrookOpenMMFloat[maxBonds];
BrookOpenMMFloat** params = new BrookOpenMMFloat*[getNumberOfParameterStreams()];
for( int ii = 0; ii < getNumberOfParameterStreams(); ii++ ){
params[ii] = new BrookOpenMMFloat[4*maxBonds];
}
// ---------------------------------------------------------------------------------------
// build streams
// const BrookStreamFactory& brookStreamFactory = dynamic_cast<const BrookStreamFactory&> (brookPlatform.getDefaultStreamFactory() );
// int particleStreamWidth = brookStreamFactory.getDefaultParticleStreamWidth();
// Initialize all particle indices to -1 to indicate empty slots
// All parameters must be initialized to values that will
// produce zero for the corresponding force.
memset( charges, 0, maxBonds*sizeof( BrookOpenMMFloat ) );
for( int ii = 0; ii < maxBonds; ii++ ){
ATOMS( ii, 0 ) = -1;
ATOMS( ii, 1 ) = -1;
ATOMS( ii, 2 ) = -1;
ATOMS( ii, 3 ) = -1;
for( int jj = 0; jj < getNumberOfParameterStreams(); jj++ ){
PARAMS( ii, jj, 0 ) = 0.0;
PARAMS( ii, jj, 1 ) = 0.0;
PARAMS( ii, jj, 2 ) = 0.0;
PARAMS( ii, jj, 3 ) = 0.0;
}
//Set sigma negative to indicate no pair
PARAMS( ii, 4, 2 ) = -1.0;
}
// nbondeds tracks number of ixn
int nbondeds = 0;
if( rbTorsionBrookBondParameters ){
_addRBTorsions( &nbondeds, particles, params, rbTorsionBrookBondParameters->getParticleIndices(), rbTorsionBrookBondParameters->getBondParameters() );
}
if( periodicTorsionBrookBondParameters ){
_addPTorsions( &nbondeds, particles, params, periodicTorsionBrookBondParameters->getParticleIndices(), periodicTorsionBrookBondParameters->getBondParameters() );
}
if( harmonicAngleBrookBondParameters ){
_addAngles( &nbondeds, particles, params, harmonicAngleBrookBondParameters->getParticleIndices(), harmonicAngleBrookBondParameters->getBondParameters() );
}
if( harmonicBondBrookBondParameters ){
_addBonds( &nbondeds, particles, params, harmonicBondBrookBondParameters->getParticleIndices(), harmonicBondBrookBondParameters->getBondParameters() );
}
if( nonBonded14ForceParameters ){
_addPairs( &nbondeds, particles, params, charges, nonBonded14ForceParameters->getParticleIndices(), nonBonded14ForceParameters->getBondParameters() );
}
// ---------------------------------------------------------------------------------------
// check that number of bonds not too large for memory allocated
if( nbondeds >= maxBonds ){
std::stringstream message;
message << methodName << " number of bonds=" << nbondeds << " is greater than maxBonds=" << maxBonds << " numberOfParticles=" << numberOfParticles;
throw OpenMMException( message.str() );
} else if( nbondeds < 1 ){
// return if no bonds
if( printOn || getLog() ){
(void) fprintf( getLog(), "%s WARNING: particles=%d number of bonds=%d maxBonds=%d\n", methodName.c_str(), numberOfParticles, nbondeds, maxBonds );
}
_setupCompleted = 1;
return DefaultReturnValue;
} else if( printOn ){
(void) fprintf( log, "%s particles=%d number of bonds=%d maxBonds=%d\n", methodName.c_str(), numberOfParticles, nbondeds, maxBonds );
(void) fflush( log );
}
// ---------------------------------------------------------------------------------------
// charge stream
_chargeStream = new BrookFloatStreamInternal( BrookCommon::BondedChargeStream, nbondeds, particleStreamWidth,
BrookStreamInternal::Float, dangleValue );
// ---------------------------------------------------------------------------------------
// particle indices stream
_particleIndicesStream = new BrookFloatStreamInternal( BrookCommon::BondedParticleIndicesStream, nbondeds, particleStreamWidth,
BrookStreamInternal::Float4, dangleValue );
int* buffer = new int[4*_particleIndicesStream->getStreamSize()];
memset( buffer, 0, sizeof( int )*4*_particleIndicesStream->getStreamSize() );
int index = 0;
for( int ii = 0; ii < nbondeds; ii++ ){
for( int jj = 0; jj < 4; jj++ ){
buffer[index++] = ATOMS( ii, jj );
//(void) fprintf( getLog(), "%s particleIndices %d %d %d buffer=%d particles=%d\n", methodName.c_str(), ii, jj, index, buffer[index-1], ATOMS( ii, jj ) );
}
}
_particleIndicesStream->loadFromArray( buffer, BrookStreamInternal::Integer );
delete[] buffer;
// ---------------------------------------------------------------------------------------
_chargeStream->loadFromArray( charges );
// ---------------------------------------------------------------------------------------
// bonded parameters
for( int ii = 0; ii < getNumberOfParameterStreams(); ii++ ){
_bondedParameters[ii] = new BrookFloatStreamInternal( BrookCommon::BondedParametersStream, nbondeds, particleStreamWidth,
BrookStreamInternal::Float4, dangleValue );
_bondedParameters[ii]->loadFromArray( params[ii] );
}
// ---------------------------------------------------------------------------------------
// printOn stuff
if( printOn ){
(void) fprintf( log, "%s nbondeds=%d strDim [%d %d ] sz=%d\n", methodName.c_str(), nbondeds,
_particleIndicesStream->getStreamWidth(),
_particleIndicesStream->getStreamHeight(),
_particleIndicesStream->getStreamSize() );
(void) fflush( log );
int kIndex = 0;
int jIndex = 1;
int iIndex = 2;
int lIndex = 3;
int mIndex = 4;
/*
* float4 parm0 (rbc[1], rbc[2], rbc[3], rbc[4])
* float4 parm1 (rbc[5], cp, phi, mult) latter three are for pdih
* float4 parm2 (theta, k, theta, k ) angles i-j-k and j-k-l
* float4 parm3 (x0, k, x0, k) bonds i-j, j-k
* float4 parm4 (x0, k, sig14, eps14) bond k-l, i-l
*/
(void) fprintf( log, "\nParams\n" );
int index = 0;
for( int ii = 0; ii < 4*nbondeds; ii += 4, index++ ){
// #define PARAMS(X,Y,Z) (params[(Y)][4*(X) + Z])
(void) fprintf( log, "\n%4d [%4d %4d %4d %4d]\n"
" rb[%10.6f %10.6f %10.6f %10.6f %10.6f]\n"
" phi[%10.6f %6.1f %5.1f]\n"
" ang[%6.3f %8.2f] [%6.3f %8.2f]\n"
" h[%8.5f %14.6e] [%8.5f %14.6e] [%8.5f %14.6e]\n"
" 14[%15.6e %15.6e] q14=%15.6e\n", index,
ATOMS(index, 0), ATOMS(index, 1), ATOMS(index, 2), ATOMS(index, 3),
params[kIndex][ii], params[kIndex][ii+1], params[kIndex][ii+2], params[kIndex][ii+3], params[jIndex][ii],
params[jIndex][ii+1], params[jIndex][ii+2], params[jIndex][ii+3],
params[iIndex][ii], params[iIndex][ii+1], params[iIndex][ii+2], params[iIndex][ii+3],
params[lIndex][ii], params[lIndex][ii+1], params[lIndex][ii+2], params[lIndex][ii+3],
params[mIndex][ii], params[mIndex][ii+1], params[mIndex][ii+2], params[mIndex][ii+3], charges[index] );
}
}
// load inverse maps to streams
if( printOn ){
(void) fprintf( log, "\n_loadInvMaps %d %d %d %d\n", nbondeds, getNumberOfParticles(), particleStreamWidth, particleStreamSize ); (void) fflush( getLog() );
}
_loadInvMaps( nbondeds, getNumberOfParticles(), particles, particleStreamWidth, particleStreamSize );
// ---------------------------------------------------------------------------------------
// free memory
for( int ii = 0; ii < getNumberOfParameterStreams(); ii++ ){
delete[] params[ii];
}
delete[] params;
delete[] particles;
delete[] charges;
// initialize output streams
for( int ii = 0; ii < getNumberOfForceStreams(); ii++ ){
_bondedForceStreams[ii] = new BrookFloatStreamInternal( BrookCommon::UnrolledForceStream, nbondeds, particleStreamWidth,
BrookStreamInternal::Float3, dangleValue );
}
_setupCompleted = 1;
return DefaultReturnValue;
}
/*
* Get contents of object
*
*
* @param level level of dump
*
* @return string containing contents
*
* */
std::string BrookBonded::getContentsString( int level ) const {
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookBonded::getContentsString";
static const unsigned int MAX_LINE_CHARS = 256;
char value[MAX_LINE_CHARS];
static const char* Set = "Set";
static const char* NotSet = "Not set";
// ---------------------------------------------------------------------------------------
std::stringstream message;
std::string tab = " ";
#ifdef _MSC_VER
#define LOCAL_SPRINTF(a,b,c) sprintf_s( (a), MAX_LINE_CHARS, (b), (c) );
#define LOCAL_2_SPRINTF(a,b,c,d) sprintf_s( (a), MAX_LINE_CHARS, (b), (c), (d) );
#else
#define LOCAL_SPRINTF(a,b,c) sprintf( (a), (b), (c) );
#define LOCAL_2_SPRINTF(a,b,c,d) sprintf( (a), (b), (c), (d) );
#endif
(void) LOCAL_SPRINTF( value, "%d", getNumberOfParticles() );
message << _getLine( tab, "Number of particles:", value );
(void) LOCAL_SPRINTF( value, "%d", getInverseMapStreamWidth() );
message << _getLine( tab, "Inverse map stream width:", value );
/*
(void) LOCAL_SPRINTF( value, "%d", getParticleStreamWidth() );
message << _getLine( tab, "Particle stream width:", value );
(void) LOCAL_SPRINTF( value, "%d", getParticleStreamHeight() );
message << _getLine( tab, "Particle stream height:", value );
(void) LOCAL_SPRINTF( value, "%d", getParticleStreamSize() );
message << _getLine( tab, "Particle stream size:", value );
*/
(void) LOCAL_SPRINTF( value, "%d", getNumberOfParameterStreams() );
message << _getLine( tab, "Number of parameter streams:", value );
for( int ii = 0; ii < getNumberOfParameterStreams(); ii++ ){
char description[256];
(void) LOCAL_SPRINTF( description, "Parameter stream %d", ii );
message << _getLine( tab, description, (isParameterStreamSet(ii) ? Set : NotSet) );
}
(void) LOCAL_SPRINTF( value, "%d", getMaxInverseMapStreamCount() )
message << _getLine( tab, "Max inverseMap count:", value );
for( int ii = 0; ii < getNumberOfForceStreams(); ii++ ){
char description[256];
(void) LOCAL_SPRINTF( description, "Inverse map count %d", ii );
std::string checkInverseMap = checkInverseMapStream( ii );
(void) LOCAL_2_SPRINTF( value, "%d %s", getInverseMapStreamCount( ii ), checkInverseMap.c_str() );
message << _getLine( tab, description, value );
}
message << _getLine( tab, "Log:", (getLog() ? Set : NotSet) );
message << _getLine( tab, "Particle indices stream:", (getParticleIndicesStream() ? Set : NotSet) );
//message << _getLine( tab, "Charge stream:", (getChargeStream() ? Set : NotSet) );
(void) LOCAL_SPRINTF( value, "%d", getNumberOfForceStreams() );
message << _getLine( tab, "Number of force streams:", value );
for( int ii = 0; ii < getNumberOfForceStreams(); ii++ ){
char description[256];
(void) LOCAL_SPRINTF( description, "Force stream %d", ii );
message << _getLine( tab, description, (isForceStreamSet(ii) ? Set : NotSet) );
}
#undef LOCAL_SPRINTF
#undef LOCAL_2_SPRINTF
return message.str();
}
/*
* Helper functions for building inverse maps for
* torsions, impropers and angles.
*
* For each particle, calculates the positions at which it's
* forces are to be picked up from and stores the position
* in the appropriate index.
*
* Input: number of torsions, the particle indices, and a flag indicating
* whether we're doing i(0), j(1), k(2) or l(3)
* Output: an array of counts per particle
* arrays of inversemaps
* nimaps - the number of invmaps actually used.
*
* @param posflag 0-niparticles-1
* @param niparticles 3 for angles, 4 for torsions, impropers
* @param nints number of interactions
* @param nparticles number of particles
* @param *particles gromacs interaction list
* @param nmaps maximum number of inverse maps
* @param counts[] output counts of how many places each particle occurs
* @param *invmaps[] output array of nmaps inverse maps
* @param *nimaps, output max number of inverse maps actually used
*
* @return DefaultReturnValue, unless error in which case exits w/ OpenMM exception
*
**/
int BrookBonded::_gpuCalcInvMap( int posflag, int niparticles, int nints, int nparticles,
int *particles, int nmaps, int counts[], float4 *invmaps[],
int *nimaps ){
// ---------------------------------------------------------------------------------------
int i, j;
int particle;
int mapnum, mapcomp;
static const std::string methodName = "BrookBonded::_gpuCalcInvMap";
static const unsigned int MAX_LINE_CHARS = 256;
//char value[MAX_LINE_CHARS];
static const char* Set = "Set";
static const char* NotSet = "Not set";
int printOn = 0;
FILE* log;
int particleRange[2] = { 90000000, -90000000 };
int mapnumRange[2] = { 90000000, -90000000 };
// ---------------------------------------------------------------------------------------
if( printOn && getLog() ){
log = getLog();
} else {
printOn = 0;
}
memset( counts, 0, sizeof( int )*nparticles );
for( i = 0; i < nmaps; i++ ){
for( j = 0; j < nparticles; j++ ){
invmaps[i][j] = float4( -1.0, -1.0, -1.0, -1.0 );
}
}
//This will hold the number of imaps actually used
*nimaps = -1;
//Now note down the positions where each particle occurs
if( printOn ){
(void) fprintf( log, "%s: pos=%d ni=%d nints=%d nparticles=%d nmaps=<%d>\n", methodName.c_str(), posflag, niparticles, nints, nparticles, nmaps );
(void) fflush( log );
}
for( i = 0; i < nints; i++ ){
//This is our particle
particle = particles[ (niparticles + 1) * i + posflag + 1 ];
//Special for merged bondeds
if ( particle == -1 ){
continue;
}
if( particle < particleRange[0] ){
particleRange[0] = particle;
}
if( particle > particleRange[1] ){
particleRange[1] = particle;
}
//Check to make sure we're inside the limits
if ( counts[particle] > nmaps * 4 ){
if( printOn ){
(void) fprintf( log, "%s Particle %d has too many proper torsions (%d, max %d)\n",
methodName.c_str(), particle, counts[particle], nmaps*4 );
(void) fflush( log );
}
std::stringstream message;
message << methodName << " Particle " << particle << " has too many proper torsions; valid range:(" << counts[particle] << ", " << nmaps*4 << ")";
throw OpenMMException( message.str() );
}
//Which invmap will this go into
mapnum = counts[particle] / 4;
if ( mapnum > *nimaps )
*nimaps = mapnum;
//Which component will it be
mapcomp = counts[particle] % 4;
//Set it
//This is silly, but otherwise I have to declare it as float*
//and things get even more confusing. :)
switch (mapcomp){
case 0: invmaps[mapnum][particle].x = (float) i; break;
case 1: invmaps[mapnum][particle].y = (float) i; break;
case 2: invmaps[mapnum][particle].z = (float) i; break;
case 3: invmaps[mapnum][particle].w = (float) i; break;
default:
if( printOn ){
(void) fprintf( log, "mapcomp %d invalid -- impossible!\n", mapcomp );
(void) fflush( log );
}
std::stringstream message;
message << methodName << " mapcomp " << mapcomp << " invalid -- actually impossible!";
throw OpenMMException( message.str() );
break;
}
counts[particle]++;
if( mapnum < mapnumRange[0] ){
mapnumRange[0] = mapnum;
}
if( mapnum > mapnumRange[1] ){
mapnumRange[1] = mapnum;
}
//fprintf( gpu->log, "%d particle=%d mapcomp=%d counts[]=%d mapnum=%d\n", i, particle, mapcomp, counts[particle], mapnum );
}
(*nimaps)++;
if( printOn ){
(void) fprintf( log, "%s mnmaps=%d Ranges: particle [%d %d] mapnum [%d %d]\n",
methodName.c_str(), *nimaps, particleRange[0], particleRange[1], mapnumRange[0], mapnumRange[1] );
(void) fflush( log );
}
return DefaultReturnValue;
}
void BrookBonded::_gpuPrintInvMaps( int nmaps, int nparticles, int counts[], float4 *invmap[], FILE* logFile ){
int i;
int j;
for( i = 0; i < nparticles; i++ ){
fprintf( logFile, "%d %d ", i, counts[i] );
for( j = 0; j < nmaps; j++ ){
fprintf( logFile, "%6.0f %6.0f %6.0f %6.0f", invmap[j][i].x, invmap[j][i].y,
invmap[j][i].z, invmap[j][i].w );
}
fprintf( logFile, "\n");
}
}
/* We are still plagued by kernel call overheads. This is for a big fat
* merged inverse gather kernel:
* Since we have 32 bit floats, we have 23 bits of mantissa or the largest
* integer we can represent is 2^23. So it should be quite safe to add
* 100000 * n to the index where n is the stream in which we should do the
* lookup. This assumes that nints < 100000, preferably nints << 100000
* which should always be true
* */
int BrookBonded::_gpuCalcInvMap_merged(
int nints, //number of interactions
int nparticles, //number of particles
int *particles, //ijkl,ijkl,ijkl...
int nmaps, //maximum number of inverse maps
int counts[], //output counts of how many places each particle occurs
float4 *invmaps[], //output array of nmaps inverse maps
int *nimaps //output max number of inverse maps actually used
){
int i, j;
int particle;
int mapnum, mapcomp;
int pos;
for( i = 0; i < nparticles; i++ )
counts[i] = 0;
for( i = 0; i < nmaps; i++ ){
for( j = 0; j < nparticles; j++ ){
invmaps[i][j] = float4( -1.0, -1.0, -1.0, -1.0 );
}
}
//This will hold the number of imaps actually used
*nimaps = -1;
//For each particle
for( i = 0; i < nints; i++ ){
for( j = 0; j < 4; j++ ){
particle = particles[ i * 4 + j ];
if ( particle == -1 ){
//Nothing to be done for this particle, go to next
continue;
}
//Which map
mapnum = counts[ particle ] / 4;
//Make sure we have space
if ( mapnum >= nmaps ){
printf( "Particle %d has too many bondeds(%d, max %d)\n",
particle, counts[particle], nmaps * 4 );
return 0;
}
if ( mapnum > *nimaps ){
*nimaps = mapnum;
}
//Which component
mapcomp = counts[ particle ] % 4;
//Encode target stream and position
pos = 100000 * j + i;
switch ( mapcomp ){
case 0: invmaps[mapnum][particle].x = (float) pos; break;
case 1: invmaps[mapnum][particle].y = (float) pos; break;
case 2: invmaps[mapnum][particle].z = (float) pos; break;
case 3: invmaps[mapnum][particle].w = (float) pos; break;
}
counts[ particle ]++;
}
}
(*nimaps)++;
return 1;
}
/* Repacks the invmap streams for more efficient access in the
* merged inverse gather kernel
*
* buf should be nimaps * nparticles large.
* */
int BrookBonded::_gpuRepackInvMap_merged( int nparticles, int nmaps, int *counts,
float4 *invmaps[], float4 *buf ){
int i, j;
int nmaps_i;
for( i = 0; i < nparticles; i++ ){
for( j = 0; j < nmaps; j++ ){
buf[ i + j*nparticles ] = float4( -1.0f, -1.0f, -1.0f, -1.0f );
}
}
for( i = 0; i < nparticles; i++ ){
nmaps_i = counts[i] / 4;
if ( counts[i] % 4 )
nmaps_i++;
for( j = 0; j < nmaps_i; j++ ){
buf[ i + j * nparticles ] = invmaps[j][i];
}
}
return 1;
}
/**
* Compute forces
*
*/
void BrookBonded::computeForces( BrookStreamImpl& positionStream, BrookStreamImpl& forceStream ){
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookBonded::computeForces";
static int printOn = 0;
FILE* log;
static const int I_Stream = 0;
static const int J_Stream = 1;
static const int K_Stream = 2;
static const int L_Stream = 3;
static const int MaxErrorMessages = 2;
static int ErrorMessages = 0;
// ---------------------------------------------------------------------------------------
if( printOn && getLog() ){
log = getLog();
} else {
printOn = 0;
}
// bonded
float epsfac = (float) (getCoulombFactor());
float width = (float) (getInverseMapStreamWidth());
// bonded forces
BrookFloatStreamInternal** bondedParameters = getBondedParameterStreams();
BrookFloatStreamInternal** bondedForceStreams = getBondedForceStreams();
BrookFloatStreamInternal** inverseStreamMaps[4];
inverseStreamMaps[0] = getInverseStreamMapsStreams( 0 );
inverseStreamMaps[1] = getInverseStreamMapsStreams( 1 );
inverseStreamMaps[2] = getInverseStreamMapsStreams( 2 );
inverseStreamMaps[3] = getInverseStreamMapsStreams( 3 );
kbonded_CDLJ( epsfac,
(float) bondedForceStreams[0]->getStreamWidth(),
positionStream.getBrookStream(),
getChargeStream()->getBrookStream(),
getParticleIndicesStream()->getBrookStream(),
bondedParameters[0]->getBrookStream(),
bondedParameters[1]->getBrookStream(),
bondedParameters[2]->getBrookStream(),
bondedParameters[3]->getBrookStream(),
bondedParameters[4]->getBrookStream(),
bondedForceStreams[0]->getBrookStream(),
bondedForceStreams[1]->getBrookStream(),
bondedForceStreams[2]->getBrookStream(),
bondedForceStreams[3]->getBrookStream() );
// diagnostics
if( printOn ){
//FILE* log = stderr;
int countPrintInvMap[4] = { 3, 5, 2, 4 };
(void) fprintf( log, "\nPost kbonded_CDLJ: epsFac=%.6f %.6f", epsfac, getCoulombFactor());
(void) fprintf( log, "\nParticle indices stream\n" );
getParticleIndicesStream()->printToFile( log );
(void) fprintf( log, "\nCharge stream\n" );
getChargeStream()->printToFile( log );
for( int ii = 0; ii < 5; ii++ ){
(void) fprintf( log, "\nParam stream %d\n", ii );
bondedParameters[ii]->printToFile( log );
}
for( int ii = 0; ii < 4; ii++ ){
(void) fprintf( log, "\nForce stream %d\n", ii );
bondedForceStreams[ii]->printToFile( log );
}
/*
(void) fprintf( log, "\nNB1 forces" );
BrookStreamInternal* brookStreamInternalF = forceStream.getBrookStreamInternal();
brookStreamInternalF->printToFile( log );
*/
(void) fprintf( log, "\nInverse map streams\n" );
for( int ii = 0; ii < 4; ii++ ){
(void) fprintf( log, "\nInverse map streams -- StreamIndex=%d cnt=%d\n", ii, getInverseMapStreamCount( ii ) );
for( int jj = 0; jj < countPrintInvMap[ii]; jj++ ){
(void) fprintf( log, "\n Inverse map streams index=%d %d\n", ii, jj );
inverseStreamMaps[ii][jj]->printToFile( log );
}
}
}
// gather forces
if( getInverseMapStreamCount( I_Stream ) == 3 && getInverseMapStreamCount( K_Stream ) == 3 ){
kinvmap_gather3_3( width,
inverseStreamMaps[I_Stream][0]->getBrookStream(),
inverseStreamMaps[I_Stream][1]->getBrookStream(),
inverseStreamMaps[I_Stream][2]->getBrookStream(),
bondedForceStreams[I_Stream]->getBrookStream(),
inverseStreamMaps[K_Stream][0]->getBrookStream(),
inverseStreamMaps[K_Stream][1]->getBrookStream(),
inverseStreamMaps[K_Stream][2]->getBrookStream(),
bondedForceStreams[K_Stream]->getBrookStream(),
forceStream.getBrookStream(), forceStream.getBrookStream() );
} else if( getInverseMapStreamCount( I_Stream ) == 2 && getInverseMapStreamCount( K_Stream ) == 2 ){
kinvmap_gather2_2( width,
inverseStreamMaps[I_Stream][0]->getBrookStream(),
inverseStreamMaps[I_Stream][1]->getBrookStream(),
bondedForceStreams[I_Stream]->getBrookStream(),
inverseStreamMaps[K_Stream][0]->getBrookStream(),
inverseStreamMaps[K_Stream][1]->getBrookStream(),
bondedForceStreams[K_Stream]->getBrookStream(),
forceStream.getBrookStream(), forceStream.getBrookStream() );
} else if( getInverseMapStreamCount( I_Stream ) == 2 && getInverseMapStreamCount( K_Stream ) == 3 ){
kinvmap_gather2_3( width,
inverseStreamMaps[I_Stream][0]->getBrookStream(),
inverseStreamMaps[I_Stream][1]->getBrookStream(),
bondedForceStreams[I_Stream]->getBrookStream(),
inverseStreamMaps[K_Stream][0]->getBrookStream(),
inverseStreamMaps[K_Stream][1]->getBrookStream(),
inverseStreamMaps[K_Stream][2]->getBrookStream(),
bondedForceStreams[K_Stream]->getBrookStream(),
forceStream.getBrookStream(), forceStream.getBrookStream() );
} else if( getInverseMapStreamCount( I_Stream ) == 3 && getInverseMapStreamCount( K_Stream ) == 4 ){
kinvmap_gather3_4( width,
inverseStreamMaps[I_Stream][0]->getBrookStream(),
inverseStreamMaps[I_Stream][1]->getBrookStream(),
inverseStreamMaps[I_Stream][2]->getBrookStream(),
bondedForceStreams[I_Stream]->getBrookStream(),
inverseStreamMaps[K_Stream][0]->getBrookStream(),
inverseStreamMaps[K_Stream][1]->getBrookStream(),
inverseStreamMaps[K_Stream][2]->getBrookStream(),
inverseStreamMaps[K_Stream][3]->getBrookStream(),
bondedForceStreams[K_Stream]->getBrookStream(),
forceStream.getBrookStream(), forceStream.getBrookStream() );
} else if( getInverseMapStreamCount( I_Stream ) == 3 && getInverseMapStreamCount( K_Stream ) == 5 ){
kinvmap_gather3_5( width,
inverseStreamMaps[I_Stream][0]->getBrookStream(),
inverseStreamMaps[I_Stream][1]->getBrookStream(),
inverseStreamMaps[I_Stream][2]->getBrookStream(),
bondedForceStreams[I_Stream]->getBrookStream(),
inverseStreamMaps[K_Stream][0]->getBrookStream(),
inverseStreamMaps[K_Stream][1]->getBrookStream(),
inverseStreamMaps[K_Stream][2]->getBrookStream(),
inverseStreamMaps[K_Stream][3]->getBrookStream(),
inverseStreamMaps[K_Stream][4]->getBrookStream(),
bondedForceStreams[K_Stream]->getBrookStream(),
forceStream.getBrookStream(), forceStream.getBrookStream() );
} else if( getInverseMapStreamCount( I_Stream ) == 3 && getInverseMapStreamCount( K_Stream ) == 2 ){
kinvmap_gather3_2( width,
inverseStreamMaps[I_Stream][0]->getBrookStream(),
inverseStreamMaps[I_Stream][1]->getBrookStream(),
inverseStreamMaps[I_Stream][2]->getBrookStream(),
bondedForceStreams[I_Stream]->getBrookStream(),
inverseStreamMaps[K_Stream][0]->getBrookStream(),
inverseStreamMaps[K_Stream][1]->getBrookStream(),
bondedForceStreams[K_Stream]->getBrookStream(),
forceStream.getBrookStream(), forceStream.getBrookStream() );
} else if( getInverseMapStreamCount( I_Stream ) == 3 && getInverseMapStreamCount( K_Stream ) == 1 ){
kinvmap_gather3_1( width,
inverseStreamMaps[I_Stream][0]->getBrookStream(),
inverseStreamMaps[I_Stream][1]->getBrookStream(),
inverseStreamMaps[I_Stream][2]->getBrookStream(),
bondedForceStreams[I_Stream]->getBrookStream(),
inverseStreamMaps[K_Stream][0]->getBrookStream(),
bondedForceStreams[K_Stream]->getBrookStream(),
forceStream.getBrookStream(), forceStream.getBrookStream() );
} else if( getInverseMapStreamCount( I_Stream ) == 2 && getInverseMapStreamCount( K_Stream ) == 4 ){
kinvmap_gather2_4( width,
inverseStreamMaps[I_Stream][0]->getBrookStream(),
inverseStreamMaps[I_Stream][1]->getBrookStream(),
bondedForceStreams[I_Stream]->getBrookStream(),
inverseStreamMaps[K_Stream][0]->getBrookStream(),
inverseStreamMaps[K_Stream][1]->getBrookStream(),
inverseStreamMaps[K_Stream][2]->getBrookStream(),
inverseStreamMaps[K_Stream][3]->getBrookStream(),
bondedForceStreams[K_Stream]->getBrookStream(),
forceStream.getBrookStream(), forceStream.getBrookStream() );
} else if( getInverseMapStreamCount( I_Stream ) == 2 && getInverseMapStreamCount( K_Stream ) == 5 ){
kinvmap_gather2_5( width,
inverseStreamMaps[I_Stream][0]->getBrookStream(),
inverseStreamMaps[I_Stream][1]->getBrookStream(),
bondedForceStreams[I_Stream]->getBrookStream(),
inverseStreamMaps[K_Stream][0]->getBrookStream(),
inverseStreamMaps[K_Stream][1]->getBrookStream(),
inverseStreamMaps[K_Stream][2]->getBrookStream(),
inverseStreamMaps[K_Stream][3]->getBrookStream(),
inverseStreamMaps[K_Stream][4]->getBrookStream(),
bondedForceStreams[K_Stream]->getBrookStream(),
forceStream.getBrookStream(), forceStream.getBrookStream() );
} else if( getInverseMapStreamCount( I_Stream ) == 2 && getInverseMapStreamCount( K_Stream ) == 1 ){
kinvmap_gather2_1( width,
inverseStreamMaps[I_Stream][0]->getBrookStream(),
inverseStreamMaps[I_Stream][1]->getBrookStream(),
bondedForceStreams[I_Stream]->getBrookStream(),
inverseStreamMaps[K_Stream][0]->getBrookStream(),
bondedForceStreams[K_Stream]->getBrookStream(),
forceStream.getBrookStream(), forceStream.getBrookStream() );
} else if( getInverseMapStreamCount( I_Stream ) == 1 && getInverseMapStreamCount( K_Stream ) == 1 ){
kinvmap_gather1_1( width,
inverseStreamMaps[I_Stream][0]->getBrookStream(),
bondedForceStreams[I_Stream]->getBrookStream(),
inverseStreamMaps[K_Stream][0]->getBrookStream(),
bondedForceStreams[K_Stream]->getBrookStream(),
forceStream.getBrookStream(), forceStream.getBrookStream() );
} else {
// case not handled -- throw an exception
FILE* log = getLog() ? getLog() : stderr;
if( ErrorMessages++ < MaxErrorMessages && getInverseMapStreamCount( I_Stream ) > 0 && getInverseMapStreamCount( K_Stream ) > 0 ){
(void) fprintf( log, "%s case: I-map=%d K-map=%d -- not handled.\n",
methodName.c_str(), getInverseMapStreamCount( I_Stream ),
getInverseMapStreamCount( K_Stream ) );
(void) fflush( log );
}
kinvmap_gather3_3( width,
inverseStreamMaps[I_Stream][0]->getBrookStream(),
inverseStreamMaps[I_Stream][1]->getBrookStream(),
inverseStreamMaps[I_Stream][2]->getBrookStream(),
bondedForceStreams[I_Stream]->getBrookStream(),
inverseStreamMaps[K_Stream][0]->getBrookStream(),
inverseStreamMaps[K_Stream][1]->getBrookStream(),
inverseStreamMaps[K_Stream][2]->getBrookStream(),
bondedForceStreams[K_Stream]->getBrookStream(),
forceStream.getBrookStream(), forceStream.getBrookStream() );
/*
std::stringstream message;
message << methodName << "I-maps=" << getInverseMapStreamCount( I_Stream ) << " and " <<
"K-maps=" << getInverseMapStreamCount( K_Stream ) << " not handled.";
throw OpenMMException( message.str() );
*/
}
// diagnostics
if( printOn ){
(void) fprintf( log, "%s Post 3_4/3_5 forces\n", methodName.c_str() );
BrookStreamInternal* brookStreamInternalF = forceStream.getBrookStreamInternal();
brookStreamInternalF->printToFile( log );
}
if( getInverseMapStreamCount( J_Stream ) == 1 && getInverseMapStreamCount( L_Stream ) == 1 ){
kinvmap_gather1_1( width,
inverseStreamMaps[J_Stream][0]->getBrookStream(),
bondedForceStreams[J_Stream]->getBrookStream(),
inverseStreamMaps[L_Stream][0]->getBrookStream(),
bondedForceStreams[L_Stream]->getBrookStream(),
forceStream.getBrookStream(), forceStream.getBrookStream() );
} else if( getInverseMapStreamCount( J_Stream ) == 5 && getInverseMapStreamCount( L_Stream ) == 2 ){
kinvmap_gather5_2( width,
inverseStreamMaps[J_Stream][0]->getBrookStream(),
inverseStreamMaps[J_Stream][1]->getBrookStream(),
inverseStreamMaps[J_Stream][2]->getBrookStream(),
inverseStreamMaps[J_Stream][3]->getBrookStream(),
inverseStreamMaps[J_Stream][4]->getBrookStream(),
bondedForceStreams[J_Stream]->getBrookStream(),
inverseStreamMaps[L_Stream][0]->getBrookStream(),
inverseStreamMaps[L_Stream][1]->getBrookStream(),
bondedForceStreams[L_Stream]->getBrookStream(),
forceStream.getBrookStream(), forceStream.getBrookStream() );
} else if( getInverseMapStreamCount( J_Stream ) == 4 && getInverseMapStreamCount( L_Stream ) == 2 ){
kinvmap_gather4_2( width,
inverseStreamMaps[J_Stream][0]->getBrookStream(),
inverseStreamMaps[J_Stream][1]->getBrookStream(),
inverseStreamMaps[J_Stream][2]->getBrookStream(),
inverseStreamMaps[J_Stream][3]->getBrookStream(),
bondedForceStreams[J_Stream]->getBrookStream(),
inverseStreamMaps[L_Stream][0]->getBrookStream(),
inverseStreamMaps[L_Stream][1]->getBrookStream(),
bondedForceStreams[L_Stream]->getBrookStream(),
forceStream.getBrookStream(), forceStream.getBrookStream() );
} else if( getInverseMapStreamCount( J_Stream ) == 3 && getInverseMapStreamCount( L_Stream ) == 2 ){
kinvmap_gather3_2( width,
inverseStreamMaps[J_Stream][0]->getBrookStream(),
inverseStreamMaps[J_Stream][1]->getBrookStream(),
inverseStreamMaps[J_Stream][2]->getBrookStream(),
bondedForceStreams[J_Stream]->getBrookStream(),
inverseStreamMaps[L_Stream][0]->getBrookStream(),
inverseStreamMaps[L_Stream][1]->getBrookStream(),
bondedForceStreams[L_Stream]->getBrookStream(),
forceStream.getBrookStream(), forceStream.getBrookStream() );
} else if( getInverseMapStreamCount( J_Stream ) == 2 && getInverseMapStreamCount( L_Stream ) == 2 ){
kinvmap_gather2_2( width,
inverseStreamMaps[J_Stream][0]->getBrookStream(),
inverseStreamMaps[J_Stream][1]->getBrookStream(),
bondedForceStreams[J_Stream]->getBrookStream(),
inverseStreamMaps[L_Stream][0]->getBrookStream(),
inverseStreamMaps[L_Stream][1]->getBrookStream(),
bondedForceStreams[L_Stream]->getBrookStream(),
forceStream.getBrookStream(), forceStream.getBrookStream() );
} else if( getInverseMapStreamCount( J_Stream ) == 1 && getInverseMapStreamCount( L_Stream ) == 2 ){
kinvmap_gather1_2( width,
inverseStreamMaps[J_Stream][0]->getBrookStream(),
bondedForceStreams[J_Stream]->getBrookStream(),
inverseStreamMaps[L_Stream][0]->getBrookStream(),
inverseStreamMaps[L_Stream][1]->getBrookStream(),
bondedForceStreams[L_Stream]->getBrookStream(),
forceStream.getBrookStream(), forceStream.getBrookStream() );
} else if( getInverseMapStreamCount( J_Stream ) == 5 && getInverseMapStreamCount( L_Stream ) == 3 ){
kinvmap_gather5_3( width,
inverseStreamMaps[J_Stream][0]->getBrookStream(),
inverseStreamMaps[J_Stream][1]->getBrookStream(),
inverseStreamMaps[J_Stream][2]->getBrookStream(),
inverseStreamMaps[J_Stream][3]->getBrookStream(),
inverseStreamMaps[J_Stream][4]->getBrookStream(),
bondedForceStreams[J_Stream]->getBrookStream(),
inverseStreamMaps[L_Stream][0]->getBrookStream(),
inverseStreamMaps[L_Stream][1]->getBrookStream(),
inverseStreamMaps[L_Stream][2]->getBrookStream(),
bondedForceStreams[L_Stream]->getBrookStream(),
forceStream.getBrookStream(), forceStream.getBrookStream() );
} else if( getInverseMapStreamCount( J_Stream ) == 4 && getInverseMapStreamCount( L_Stream ) == 3 ){
kinvmap_gather4_3( width,
inverseStreamMaps[J_Stream][0]->getBrookStream(),
inverseStreamMaps[J_Stream][1]->getBrookStream(),
inverseStreamMaps[J_Stream][2]->getBrookStream(),
inverseStreamMaps[J_Stream][3]->getBrookStream(),
bondedForceStreams[J_Stream]->getBrookStream(),
inverseStreamMaps[L_Stream][0]->getBrookStream(),
inverseStreamMaps[L_Stream][1]->getBrookStream(),
inverseStreamMaps[L_Stream][2]->getBrookStream(),
bondedForceStreams[L_Stream]->getBrookStream(),
forceStream.getBrookStream(), forceStream.getBrookStream() );
} else {
// case not handled -- throw an exception
FILE* log = getLog() ? getLog() : stderr;
if( ErrorMessages++ < MaxErrorMessages && getInverseMapStreamCount( J_Stream ) > 0 && getInverseMapStreamCount( L_Stream ) > 0 ){
(void) fprintf( log, "%s case: J-map=%d L-map=%d -- not handled -- contact OpenMM developers.\n",
methodName.c_str(), getInverseMapStreamCount( J_Stream ),
getInverseMapStreamCount( L_Stream ) );
(void) fflush( log );
}
// this is for testing purposes a-- may need to be cleaned
// or add new gather functions
kinvmap_gather5_2( width,
inverseStreamMaps[J_Stream][0]->getBrookStream(),
inverseStreamMaps[J_Stream][1]->getBrookStream(),
inverseStreamMaps[J_Stream][2]->getBrookStream(),
inverseStreamMaps[J_Stream][3]->getBrookStream(),
inverseStreamMaps[J_Stream][4]->getBrookStream(),
bondedForceStreams[J_Stream]->getBrookStream(),
inverseStreamMaps[L_Stream][0]->getBrookStream(),
inverseStreamMaps[L_Stream][1]->getBrookStream(),
bondedForceStreams[L_Stream]->getBrookStream(),
forceStream.getBrookStream(), forceStream.getBrookStream() );
/*
std::stringstream message;
message << methodName << "J-maps=" << getInverseMapStreamCount( J_Stream ) << " and " <<
"L-maps=" << getInverseMapStreamCount( L_Stream ) << " not handled.";
throw OpenMMException( message.str() );
*/
}
// diagnostics
if( printOn ){
(void) fprintf( log, "%s Final forces", methodName.c_str() );
BrookStreamInternal* brookStreamInternalF = forceStream.getBrookStreamInternal();
brookStreamInternalF->printToFile( log );
}
// ---------------------------------------------------------------------------------------
}
#ifndef OPENMM_BROOK_BONDED_H_
#define OPENMM_BROOK_BONDED_H_
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2009 Stanford University and the Authors. *
* Authors: Mark Friedrichs, Mike Houston *
* Contributors: *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as published *
* by the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* -------------------------------------------------------------------------- */
#include <vector>
#include "BrookStreamImpl.h"
#include "BrookCommon.h"
#include "openmm/Context.h"
#include "BrookBondParameters.h"
namespace OpenMM {
/**
* Calculate Brook bonded forces
*/
class BrookBonded : public BrookCommon {
public:
/**
*
* BrookBonded constructor
*
*/
BrookBonded( );
/**
*
* BrookBonded desstructor
*
*/
~BrookBonded( );
/**
* Initialize the kernel, setting up the values of all the force field parameters.
*
* @param numberOfParticles numberOfParticles
* @param harmonicBondBrookBondParameters force parameters (length, k) for each bond term
* @param harmonicAngleBrookBondParameters force parameters (angle, k) for each angle term
* @param periodicTorsionBrookBondParameters force parameters (k, phase, periodicity) for each periodic torsion term
* @param rbTorsionBrookBondParameters coefficients (in order of increasing powers) for each Ryckaert-Bellemans torsion term
* @param nonBonded14ForceParameters nonbonded 14 force parameters (charge, sigma, epsilon) for each particle
* @param particleStreamWidth stream width
* @param particleStreamSize stream size
*
* @return nonzero value if error
*
*/
int setup( int numberOfParticles,
BrookBondParameters* harmonicBondBrookBondParameters,
BrookBondParameters* harmonicAngleBrookBondParameters,
BrookBondParameters* periodicTorsionBrookBondParameters,
BrookBondParameters* rbTorsionBrookBondParameters,
BrookBondParameters* nonBonded14ForceParameters, int particleStreamWidth, int particleStreamSize );
/**
* Get inverse map stream width
*
* @return stream width
*
*/
int getInverseMapStreamWidth( void ) const;
/**
* Return number of parameter streams
*
* @return number of parameter streams
*
*/
int getNumberOfParameterStreams( void ) const;
/**
* Return number of force streams
*
* @return number of force streams
*
*/
int getNumberOfForceStreams( void ) const;
/**
* Return stream count for specifed index (i, j, k, l)
*
* @return stream count for specifed index
*
* @throw throws OpenMMException if index out of range
*/
int getInverseMapStreamCount( int index ) const;
/**
* Return max stream count
*
* @return max stream count
*/
int getMaxInverseMapStreamCount( void ) const;
/**
* Return max stream count for specified index
*
* @param index index of force stream
*
* @return max stream count
*
*/
int getMaxInverseMapStreamCount( int index ) const;
/**
* Return Brook stream handle
*
* @return
*/
BrookFloatStreamInternal* getBrookParticleIndices( void ) const;
/**
* Get Coulomb factor
*
* @return Coulomb factor
*
*/
BrookOpenMMFloat getCoulombFactor( void ) const;
/**
* Get bonded particle indices stream
*
* @return particle indices stream
*
*/
BrookFloatStreamInternal* getParticleIndicesStream( void ) const;
/**
* Get bonded charge stream
*
* @return charge stream
*
*/
BrookFloatStreamInternal* getChargeStream( void ) const;
/**
* Get array of bonded parameter streams
*
* @return array of bonded parameter streams
*
*/
BrookFloatStreamInternal** getBondedParameterStreams( void );
/**
* Get array of force streams
*
* @return array
*
*/
BrookFloatStreamInternal** getBondedForceStreams( void );
/**
* Get array of inverse map streams
*
* @param index array index
*
* @return array inverse map streams
*
*/
BrookFloatStreamInternal** getInverseStreamMapsStreams( int index );
/**
* Return true if force[index] stream is set
*
* @param index into force stream
* @return true if index is valid && force[index] stream is set; else false
*
*/
int isForceStreamSet( int index ) const;
/**
* Return true if paramsterSet[index] stream is set
*
* @param index into parameter stream
*
* @return true if index is valid && paramsterSet[index] stream is set; else false
*
*/
int isParameterStreamSet( int index ) const;
/**
* Return string showing if all inverse map streams are set
*
* @param index into inverse map stream array
*
* @return informative string
*
*/
std::string checkInverseMapStream( int index ) const;
/*
* Get contents of object
*
*
* @param level level of dump
*
* @return string containing contents
*
* */
std::string getContentsString( int level = 0 ) const;
/**
* Compute forces
*
*/
void computeForces( BrookStreamImpl& positionStream, BrookStreamImpl& forceStream );
/**
* Return SetupCompleted flag
*
* @return SetupCompleted flag
*/
int isSetupCompleted( void ) const;
/**
* Set SetupCompleted flag
*
* @param SetupCompleted flag
*
* @return SetupCompleted flag
*/
int setupCompleted( int isSetupCompleted );
private:
static const int NumberOfParameterStreams = 5;
static const int NumberOfForceStreams = 4;
static const int MaxNumberOfInverseMaps = 9;
enum { StreamI, StreamJ, StreamK, StreamL, StreamMax };
int _setupCompleted;
// inverse map stream width
int _inverseMapStreamWidth;
// actual max number of inverse maps
int _maxNumberOfInverseMaps;
// scale factors for 1-4 ixn
BrookOpenMMFloat _coulombFactor;
// streams
BrookFloatStreamInternal* _particleIndicesStream;
BrookFloatStreamInternal* _bondedParameters[NumberOfParameterStreams];
BrookFloatStreamInternal* _bondedForceStreams[NumberOfForceStreams];
BrookFloatStreamInternal* _chargeStream;
BrookFloatStreamInternal* _inverseStreamMaps[NumberOfForceStreams][MaxNumberOfInverseMaps];
int _maxInverseMapStreamCount[NumberOfForceStreams];
int _inverseMapStreamCount[NumberOfForceStreams];
// helper methods in setup of parameters
void _flipQuartet( int ibonded, int *particles );
int _matchTorsion( int i, int j, int k, int l, int nbondeds, int *particles );
int _matchAngle( int i, int j, int k, int nbondeds, int *particles, int *flag );
int _matchBond( int i, int j, int nbondeds, int *particles, int *flag );
int _matchPair( int i, int j, int nbondeds, int *particles );
/**
* Setup Ryckaert-Bellemans parameters/particle indices
*
* @param nbondeds number of bonded entries
* @param particles array of particle indices
* @param params arrays of bond parameters
* @param rbTorsionIndices the four particles connected by each Ryckaert-Bellemans torsion term
* @param rbTorsionParameters the coefficients (in order of increasing powers) for each Ryckaert-Bellemans torsion term
*
* @return nonzero value if error
*
*/
int _addRBTorsions( int *nbondeds, int *particles, BrookOpenMMFloat* params[], const std::vector<std::vector<int> >& rbTorsionIndices,
const std::vector<std::vector<double> >& rbTorsionParameters );
/**
* Setup periodic torsion parameters/particle indices
*
* @param nbondeds number of bonded entries
* @param particles array of particle indices
* @param params arrays of bond parameters
* @param periodicTorsionIndices the four particles connected by each periodic torsion term
* @param periodicTorsionParameters the force parameters (k, phase, periodicity) for each periodic torsion term
*
* @return nonzero value if error
*
*/
int _addPTorsions( int *nbondeds, int *particles, BrookOpenMMFloat* params[], const std::vector<std::vector<int> >& periodicTorsionIndices,
const std::vector<std::vector<double> >& periodicTorsionParameters );
/**
* Setup angle bond parameters/particle indices
*
* @param nbondeds number of bonded entries
* @param particles array of particle indices
* @param params arrays of bond parameters
* @param angleIndices the angle bond particle indices
* @param angleParameters the angle parameters (angle in radians, force constant)
*
* @return nonzero value if error
*
*/
int _addAngles( int *nbondeds, int *particles, BrookOpenMMFloat* params[], const std::vector<std::vector<int> >& angleIndices,
const std::vector<std::vector<double> >& angleParameters );
/**
* Setup harmonic bond parameters/particle indices
*
* @param nbondeds number of bonded entries
* @param particles array of particle indices
* @param params arrays of bond parameters
* @param bondIndices two harmonic bond particle indices
* @param bondParameters the force parameters (distance, k)
*
* @return nonzero value if error
*
*/
int _addBonds( int *nbondeds, int *particles, BrookOpenMMFloat* params[], const std::vector<std::vector<int> >& bondIndices,
const std::vector<std::vector<double> >& bondParameters );
/**
* Setup LJ/Coulomb 1-4 parameters/particle indices
*
* @param nbondeds number of bonded entries
* @param particles array of particle indices
* @param params arrays of bond parameters
* @param charges array of charges
* @param bonded14Indices each element contains the indices of two particles whose nonbonded interactions should be reduced since
* they form a bonded 1-4 pair
* @param nonbondedParameters the nonbonded force parameters (charge, sigma, epsilon) for each particle
*
* @return nonzero value if error
*
*/
int _addPairs( int *nbondeds, int *particles, BrookOpenMMFloat* params[], BrookOpenMMFloat* charges,
const std::vector<std::vector<int> >& bonded14Indices, const std::vector<std::vector<double> >& nonbondedParameters );
/**
* Create and load inverse maps for bonded ixns
*
* @param nbondeds number of bonded entries
* @param nparticles number of particles
* @param particles arrays of particle indices (particles[numberOfBonds][4])
* @param platform BrookPlatform reference
* @param log log file reference (optional)
*
* @return nonzero value if error
*
*/
//int loadInvMaps( int nbondeds, int nparticles, int *particles, const BrookPlatform& platform );
int _loadInvMaps( int nbondeds, int nparticles, int *particles, int particleStreamWidth, int particleStreamSize );
/**
* Validate inverse map count
*
* @param index index to check (1-4)
* @param count count for index
*
* @return -1 if count invalid
*
* @tthrow OpenMMException exeception if count invalid
*
*/
int _validateInverseMapStreamCount( int index, int count ) const;
/*
* Helper functions for building inverse maps for
* torsions, impropers and angles.
*
* For each particle, calculates the positions at which it's
* forces are to be picked up from and stores the position
* in the appropriate index.
*
* Input: number of torsions, the particle indices, and a flag indicating
* whether we're doing i(0), j(1), k(2) or l(3)
* Output: an array of counts per particle
* arrays of inversemaps
* nimaps - the number of invmaps actually used.
*
* @param posflag 0-niparticles-1
* @param niparticles 3 for angles, 4 for torsions, impropers
* @param nints number of interactions
* @param nparticles number of particles
* @param *particles gromacs interaction list
* @param nmaps maximum number of inverse maps
* @param counts[] output counts of how many places each particle occurs
* @param *invmaps[] output array of nmaps inverse maps
* @param *nimaps, output max number of inverse maps actually used
*
* @return DefaultReturnValue, unless error in which case exits w/ OpenMM exception
*
**/
int _gpuCalcInvMap( int posflag, int niparticles, int nints, int nparticles,
int *particles, int nmaps, int counts[], float4 *invmaps[], int *nimaps );
void _gpuPrintInvMaps( int nmaps, int nparticles, int counts[], float4 *invmap[], FILE* logFile );
/*
* We are still plagued by kernel call overheads. This is for a big fat
* merged inverse gather kernel:
* Since we have 32 bit floats, we have 23 bits of mantissa or the largest
* integer we can represent is 2^23. So it should be quite safe to add
* 100000 * n to the index where n is the stream in which we should do the
* lookup. This assumes that nints < 100000, preferably nints << 100000
* which should always be true
*
**/
int _gpuCalcInvMap_merged( int nints, int nparticles, int *particles, int nmaps, int counts[], float4 *invmaps[], int *nimaps );
/*
* Repacks the invmap streams for more efficient access in the
* merged inverse gather kernel
*
* buf should be nimaps * nparticles large.
*
**/
int _gpuRepackInvMap_merged( int nparticles, int nmaps, int *counts, float4 *invmaps[], float4 *buf );
};
} // namespace OpenMM
#endif /* OPENMM_BROOK_BONDED_H_ */
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2009 Stanford University and the Authors. *
* Authors: Mark Friedrichs, Mike Houston *
* Contributors: *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as published *
* by the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* -------------------------------------------------------------------------- */
#include "openmm/OpenMMException.h"
#include "BrookStreamImpl.h"
#include "BrookCalcGBSAOBCForceKernel.h"
#include "kernels/kgbsa.h"
#include "kernels/kforce.h"
#include <cmath>
#include <limits>
#include <sstream>
using namespace OpenMM;
using namespace std;
/**
* BrookCalcGBSAOBCForceKernel constructor
*
* @param name kernel name
* @param platform platform
* @param OpenMMBrookInterface OpenMM-Brook interface
* @param System System reference
*
*/
BrookCalcGBSAOBCForceKernel::BrookCalcGBSAOBCForceKernel( std::string name, const Platform& platform, OpenMMBrookInterface& openMMBrookInterface, System& system ) :
CalcGBSAOBCForceKernel( name, platform ), _openMMBrookInterface( openMMBrookInterface ), _system( system ){
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "BrookCalcGBSAOBCForceKernel::BrookCalcGBSAOBCForceKernel";
// static const int debug = 1;
// ---------------------------------------------------------------------------------------
_numberOfParticles = 0;
_log = NULL;
const BrookPlatform& brookPlatform = dynamic_cast<const BrookPlatform&> (platform);
if( brookPlatform.getLog() != NULL ){
setLog( brookPlatform.getLog() );
}
_openMMBrookInterface.setNumberOfParticles( system.getNumParticles() );
}
/**
* BrookCalcGBSAOBCForceKernel destructor
*
*/
BrookCalcGBSAOBCForceKernel::~BrookCalcGBSAOBCForceKernel( ){
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "BrookCalcGBSAOBCForceKernel::BrookCalcGBSAOBCForceKernel";
// static const int debug = 1;
// ---------------------------------------------------------------------------------------
}
/**
* Get log file reference
*
* @return log file reference
*
*/
FILE* BrookCalcGBSAOBCForceKernel::getLog( void ) const {
return _log;
}
/**
* Set log file reference
*
* @param log file reference
*
* @return DefaultReturnValue
*
*/
int BrookCalcGBSAOBCForceKernel::setLog( FILE* log ){
_log = log;
return BrookCommon::DefaultReturnValue;
}
/**
* Initialize the kernel, setting up the values of all the force field parameters.
*
* @param system system this kernel will be applied to
* @param force GBSAOBCForce this kernel will be used for
*
*/
void BrookCalcGBSAOBCForceKernel::initialize( const System& system, const GBSAOBCForce& force ){
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookCalcGBSAOBCForceKernel::initialize";
int printOn = 0;
FILE* log;
// ---------------------------------------------------------------------------------------
if( printOn && getLog() ){
log = getLog();
} else {
printOn = 0;
}
// ---------------------------------------------------------------------------------------
BrookGbsa& brookGbsa = _openMMBrookInterface.getBrookGbsa();
// get parameters from force object
// and initialize brookGbsa
_numberOfParticles = system.getNumParticles();
std::vector<std::vector<double> > particleParameters( _numberOfParticles );
for( int ii = 0; ii < _numberOfParticles; ii++ ){
double charge, radius, scalingFactor;
force.getParticleParameters( ii, charge, radius, scalingFactor );
particleParameters[ii].push_back( charge );
particleParameters[ii].push_back( radius );
particleParameters[ii].push_back( scalingFactor );
}
brookGbsa.setup( particleParameters, force.getSolventDielectric(), force.getSoluteDielectric(), getPlatform() );
brookGbsa.setIsActive( 1 );
_openMMBrookInterface.setTriggerForceKernel( this );
_openMMBrookInterface.setTriggerEnergyKernel( this );
if( printOn ){
std::string contents = brookGbsa.getContentsString( );
(void) fprintf( log, "%s brookGbsa::contents\n%s", methodName.c_str(), contents.c_str() );
(void) fflush( log );
}
// ---------------------------------------------------------------------------------------
}
/**
* Compute forces given particle coordinates
*
* @param context ContextImpl context
*
*/
void BrookCalcGBSAOBCForceKernel::executeForces( ContextImpl& context ){
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "BrookCalcGBSAOBCForceKernel::executeForces";
// ---------------------------------------------------------------------------------------
if( _openMMBrookInterface.getTriggerForceKernel() == this ){
_openMMBrookInterface.computeForces( context );
}
}
/**
* Execute the kernel to calculate the OBC energy
*
* @param context ContextImpl context
*
* @return energy
*
*/
double BrookCalcGBSAOBCForceKernel::executeEnergy( ContextImpl& context ){
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "BrookCalcGBSAOBCForceKernel::executeEnergy";
// ---------------------------------------------------------------------------------------
if( _openMMBrookInterface.getTriggerEnergyKernel() == this ){
return (double) _openMMBrookInterface.computeEnergy( context, _system );
} else {
return 0.0;
}
}
#ifndef OPENMM_BROOK_CALC_GBSAOBC_FORCE_KERNEL_H_
#define OPENMM_BROOK_CALC_GBSAOBC_FORCE_KERNEL_H_
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2009 Stanford University and the Authors. *
* Authors: Mark Friedrichs, Mike Houston *
* Contributors: *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as published *
* by the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* -------------------------------------------------------------------------- */
#include "openmm/kernels.h"
#include "../../reference/src/SimTKUtilities/SimTKOpenMMRealType.h"
#include "BrookGbsa.h"
#include "OpenMMBrookInterface.h"
namespace OpenMM {
/**
* This kernel is invoked to calculate the OBC forces acting on the system.
*/
class BrookCalcGBSAOBCForceKernel : public CalcGBSAOBCForceKernel {
public:
/**
* BrookCalcGBSAOBCForceKernel constructor
*/
BrookCalcGBSAOBCForceKernel( std::string name, const Platform& platform, OpenMMBrookInterface& openMMBrookInterface, System& system );
/**
* BrookCalcGBSAOBCForceKernel destructor
*/
~BrookCalcGBSAOBCForceKernel();
/**
* Initialize the kernel, setting up the values of all the force field parameters.
*
* @param system system this kernel will be applied to
* @param force GBSAOBCForce this kernel will be used for
*
*/
void initialize( const System& system, const GBSAOBCForce& force );
/**
* Execute the kernel to calculate the forces.
*
* @param positions particle coordiantes
* @param forces output forces
*
*/
void executeForces( ContextImpl& context );
/**
* Execute the kernel to calculate the energy.
*
* @param positions particle positions
*
* @return potential energy due to the NonbondedForce
* Currently always return 0.0 since energies not calculated on gpu
*
*/
double executeEnergy( ContextImpl& context );
/**
* Set log file reference
*
* @param log file reference
*
* @return DefaultReturnValue
*
*/
int setLog( FILE* log );
/*
* Get contents of object
*
* @param level of dump
*
* @return string containing contents
*
* */
std::string getContents( int level ) const;
/**
* Get log file reference
*
* @return log file reference
*
*/
FILE* getLog( void ) const;
/**
* Get Brook GBSA reference
*
* @return Brook GBSA reference
*
*/
BrookGbsa& getBrookGbsa( void ) const;
private:
// log file reference
FILE* _log;
// number of particles
int _numberOfParticles;
// interface
OpenMMBrookInterface& _openMMBrookInterface;
// System reference
System& _system;
};
} // namespace OpenMM
#endif /* OPENMM_BROOK_CALC_GBSAOBC_FORCE_KERNEL_H_ */
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2009 Stanford University and the Authors. *
* Authors: Mark Friedrichs, Mike Houston *
* Contributors: *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as published *
* by the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* -------------------------------------------------------------------------- */
#include "openmm/OpenMMException.h"
#include "BrookCalcHarmonicAngleForceKernel.h"
#include <sstream>
using namespace OpenMM;
using namespace std;
const std::string BrookCalcHarmonicAngleForceKernel::BondName = "HarmonicAngle";
/**
* BrookCalcHarmonicAngleForceKernel constructor
*
* @param name kernel name
* @param platform platform
* @param OpenMMBrookInterface OpenMM-Brook interface
* @param System System reference
*
*/
BrookCalcHarmonicAngleForceKernel::BrookCalcHarmonicAngleForceKernel( std::string name, const Platform& platform,
OpenMMBrookInterface& openMMBrookInterface, System& system ) :
CalcHarmonicAngleForceKernel( name, platform ), _openMMBrookInterface( openMMBrookInterface ), _system( system ){
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "BrookCalcHarmonicAngleForceKernel::BrookCalcHarmonicAngleForceKernel";
// static const int debug = 1;
// ---------------------------------------------------------------------------------------
_brookBondParameters = NULL;
_log = NULL;
const BrookPlatform& brookPlatform = dynamic_cast<const BrookPlatform&> (platform);
if( brookPlatform.getLog() != NULL ){
setLog( brookPlatform.getLog() );
}
_openMMBrookInterface.setNumberOfParticles( system.getNumParticles() );
}
/**
* BrookCalcHarmonicAngleForceKernel destructor
*
*/
BrookCalcHarmonicAngleForceKernel::~BrookCalcHarmonicAngleForceKernel( ){
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "BrookCalcHarmonicAngleForceKernel::BrookCalcHarmonicAngleForceKernel";
// static const int debug = 1;
// ---------------------------------------------------------------------------------------
delete _brookBondParameters;
}
/**
* Get log file reference
*
* @return log file reference
*
*/
FILE* BrookCalcHarmonicAngleForceKernel::getLog( void ) const {
return _log;
}
/**
* Set log file reference
*
* @param log file reference
*
* @return DefaultReturnValue
*
*/
int BrookCalcHarmonicAngleForceKernel::setLog( FILE* log ){
_log = log;
return BrookCommon::DefaultReturnValue;
}
/**
* Initialize the kernel, setting up the values of all the force field parameters.
*
* @param system System reference
* @param force HarmonicAngleForce reference
*
*/
void BrookCalcHarmonicAngleForceKernel::initialize( const System& system, const HarmonicAngleForce& force ){
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookCalcHarmonicAngleForceKernel::initialize";
// ---------------------------------------------------------------------------------------
FILE* log = getLog();
// ---------------------------------------------------------------------------------------
// create _brookBondParameters object containing particle indices/parameters
int numberOfBonds = force.getNumAngles();
if( _brookBondParameters ){
delete _brookBondParameters;
}
_brookBondParameters = new BrookBondParameters( BrookCalcHarmonicAngleForceKernel::BondName, NumberOfParticlesInBond, NumberOfParametersInBond, numberOfBonds, getLog() );
for( int ii = 0; ii < numberOfBonds; ii++ ){
int particle1, particle2, particle3;
double angle, k;
int particles[NumberOfParticlesInBond];
double parameters[NumberOfParametersInBond];
force.getAngleParameters( ii, particle1, particle2, particle3, angle, k );
particles[0] = particle1;
particles[1] = particle2;
particles[2] = particle3;
parameters[0] = angle;
parameters[1] = k;
_brookBondParameters->setBond( ii, particles, parameters );
}
_openMMBrookInterface.setHarmonicAngleForceParameters( _brookBondParameters );
_openMMBrookInterface.setTriggerForceKernel( this );
_openMMBrookInterface.setTriggerEnergyKernel( this );
if( log ){
std::string contents = _brookBondParameters->getContentsString( );
(void) fprintf( log, "%s brookGbsa::contents\n%s", methodName.c_str(), contents.c_str() );
(void) fflush( log );
}
// ---------------------------------------------------------------------------------------
}
/**
* Compute forces given particle coordinates
*
* @param context ContextImpl context
*
*/
void BrookCalcHarmonicAngleForceKernel::executeForces( ContextImpl& context ){
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "BrookCalcHarmonicAngleForceKernel::executeForces";
// ---------------------------------------------------------------------------------------
if( _openMMBrookInterface.getTriggerForceKernel() == this ){
_openMMBrookInterface.computeForces( context );
}
return;
// ---------------------------------------------------------------------------------------
}
/**
* Execute the kernel to calculate the energy
*
* @param context ContextImpl context
*
* @return potential energy
*
*/
double BrookCalcHarmonicAngleForceKernel::executeEnergy( ContextImpl& context ){
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "BrookCalcHarmonicAngleForceKernel::executeEnergy";
// ---------------------------------------------------------------------------------------
if( _openMMBrookInterface.getTriggerEnergyKernel() == this ){
return (double) _openMMBrookInterface.computeEnergy( context, _system );
} else {
return 0.0;
}
}
#ifndef OPENMM_BROOK_CALC_HARMONIC_ANGLE_FORCE_KERNEL_H_
#define OPENMM_BROOK_CALC_HARMONIC_ANGLE_FORCE_KERNEL_H_
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2009 Stanford University and the Authors. *
* Authors: Mark Friedrichs, Mike Houston *
* Contributors: *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as published *
* by the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* -------------------------------------------------------------------------- */
#include "openmm/kernels.h"
#include "BrookPlatform.h"
#include "BrookBondParameters.h"
#include "OpenMMBrookInterface.h"
namespace OpenMM {
/**
* This kernel is invoked to calculate the harmonic angle forces acting on the system.
*/
class BrookCalcHarmonicAngleForceKernel : public CalcHarmonicAngleForceKernel {
public:
/**
* BrookCalcHarmonicAngleForceKernel constructor
*/
BrookCalcHarmonicAngleForceKernel( std::string name, const Platform& platform, OpenMMBrookInterface& openMMBrookInterface, System& system );
/**
* BrookCalcHarmonicAngleForceKernel destructor
*/
~BrookCalcHarmonicAngleForceKernel();
/**
* Initialize the kernel, setting up the values to calculate harmonic bond force & energy
*
* @param system System reference
* @param force HarmonicAngleForce reference
*
*/
void initialize( const System& system, const HarmonicAngleForce& force );
/**
* Execute the kernel to calculate the forces.
*
* @param positions particle coordiantes
* @param forces output forces
*
*/
void executeForces( ContextImpl& context );
/**
* Execute the kernel to calculate the energy.
*
* @param context the context in which to execute this kernel
*
* @return potential energy associated with the harmonic angle force
*
*/
double executeEnergy( ContextImpl& context );
/**
* Set log file reference
*
* @param log file reference
*
* @return DefaultReturnValue
*
*/
int setLog( FILE* log );
/*
* Get contents of object
*
* @param level of dump
*
* @return string containing contents
*
* */
std::string getContents( int level ) const;
/**
* Get log file reference
*
* @return log file reference
*
*/
FILE* getLog( void ) const;
/**
* Get number of bonds
*
* @return number of bonds
*
*/
int getNumberOfBonds( void ) const;
/**
* Get indices/parameters
*
* @return BrookBondParameters containing particle indices/parameters
*
*/
BrookBondParameters* getBrookBondParameters( void ) const;
private:
static const int NumberOfParticlesInBond = 3;
static const int NumberOfParametersInBond = 2;
// bond name
static const std::string BondName;
// log file reference
FILE* _log;
// Brook bond parameters
BrookBondParameters* _brookBondParameters;
// interface
OpenMMBrookInterface& _openMMBrookInterface;
// System reference
System& _system;
};
} // namespace OpenMM
#endif /* OPENMM_BROOK_CALC_HARMONIC_ANGLE_FORCE_KERNEL_H_ */
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2009 Stanford University and the Authors. *
* Authors: Mark Friedrichs, Mike Houston *
* Contributors: *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as published *
* by the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* -------------------------------------------------------------------------- */
#include "openmm/OpenMMException.h"
#include "BrookCalcHarmonicBondForceKernel.h"
#include <sstream>
using namespace OpenMM;
using namespace std;
const std::string BrookCalcHarmonicBondForceKernel::BondName = "HarmonicBond";
/**
* BrookCalcHarmonicBondForceKernel constructor
*
* @param name kernel name
* @param platform platform
* @param OpenMMBrookInterface OpenMM-Brook interface
* @param System System reference
*
*/
BrookCalcHarmonicBondForceKernel::BrookCalcHarmonicBondForceKernel( std::string name, const Platform& platform,
OpenMMBrookInterface& openMMBrookInterface, System& system ) :
CalcHarmonicBondForceKernel( name, platform ), _openMMBrookInterface( openMMBrookInterface ), _system( system ){
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "BrookCalcHarmonicBondForceKernel::BrookCalcHarmonicBondForceKernel";
// static const int debug = 1;
// ---------------------------------------------------------------------------------------
_brookBondParameters = NULL;
_log = NULL;
const BrookPlatform& brookPlatform = dynamic_cast<const BrookPlatform&> (platform);
if( brookPlatform.getLog() != NULL ){
setLog( brookPlatform.getLog() );
}
_openMMBrookInterface.setNumberOfParticles( system.getNumParticles() );
}
/**
* BrookCalcHarmonicBondForceKernel destructor
*
*/
BrookCalcHarmonicBondForceKernel::~BrookCalcHarmonicBondForceKernel( ){
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "BrookCalcHarmonicBondForceKernel::BrookCalcHarmonicBondForceKernel";
// static const int debug = 1;
// ---------------------------------------------------------------------------------------
delete _brookBondParameters;
}
/**
* Get log file reference
*
* @return log file reference
*
*/
FILE* BrookCalcHarmonicBondForceKernel::getLog( void ) const {
return _log;
}
/**
* Set log file reference
*
* @param log file reference
*
* @return DefaultReturnValue
*
*/
int BrookCalcHarmonicBondForceKernel::setLog( FILE* log ){
_log = log;
return BrookCommon::DefaultReturnValue;
}
/**
* Initialize the kernel, setting up the values of all the force field parameters.
*
* @param system System reference
* @param force HarmonicBondForce reference
*
*/
void BrookCalcHarmonicBondForceKernel::initialize( const System& system, const HarmonicBondForce& force ){
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookCalcHarmonicBondForceKernel::initialize";
int printOn = 0;
FILE* log;
// ---------------------------------------------------------------------------------------
if( printOn && getLog() ){
log = getLog();
} else {
printOn = 0;
}
// ---------------------------------------------------------------------------------------
// create _brookBondParameters object containing particle indices/parameters
int numberOfBonds = force.getNumBonds();
if( _brookBondParameters ){
delete _brookBondParameters;
}
_brookBondParameters = new BrookBondParameters( BrookCalcHarmonicBondForceKernel::BondName, NumberOfParticlesInBond, NumberOfParametersInBond, numberOfBonds, getLog() );
for( int ii = 0; ii < numberOfBonds; ii++ ){
int particle1, particle2;
double length, k;
int particles[NumberOfParticlesInBond];
double parameters[NumberOfParametersInBond];
force.getBondParameters( ii, particle1, particle2, length, k );
particles[0] = particle1;
particles[1] = particle2;
parameters[0] = length;
parameters[1] = k;
_brookBondParameters->setBond( ii, particles, parameters );
}
_openMMBrookInterface.setHarmonicBondForceParameters( _brookBondParameters );
_openMMBrookInterface.setTriggerForceKernel( this );
_openMMBrookInterface.setTriggerEnergyKernel( this );
if( printOn ){
std::string contents = _brookBondParameters->getContentsString( );
(void) fprintf( log, "%s contents\n%s", methodName.c_str(), contents.c_str() );
(void) fflush( log );
}
// ---------------------------------------------------------------------------------------
}
/**
* Compute forces given particle coordinates
*
* @param context ContextImpl context
*
*/
void BrookCalcHarmonicBondForceKernel::executeForces( ContextImpl& context ){
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookCalcHarmonicBondForceKernel::executeForces";
// ---------------------------------------------------------------------------------------
if( _openMMBrookInterface.getTriggerForceKernel() == this ){
_openMMBrookInterface.computeForces( context );
}
return;
// ---------------------------------------------------------------------------------------
}
/**
* Execute the kernel to calculate the energy
*
* @param context ContextImpl context
*
* @return potential energy
*
*/
double BrookCalcHarmonicBondForceKernel::executeEnergy( ContextImpl& context ){
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "BrookCalcHarmonicBondForceKernel::executeEnergy";
// ---------------------------------------------------------------------------------------
if( _openMMBrookInterface.getTriggerEnergyKernel() == this ){
return (double) _openMMBrookInterface.computeEnergy( context, _system );
} else {
return 0.0;
}
}
#ifndef OPENMM_BROOK_CALC_HARMONIC_BOND_FORCE_KERNEL_H_
#define OPENMM_BROOK_CALC_HARMONIC_BOND_FORCE_KERNEL_H_
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2009 Stanford University and the Authors. *
* Authors: Mark Friedrichs, Mike Houston *
* Contributors: *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as published *
* by the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* -------------------------------------------------------------------------- */
#include "openmm/kernels.h"
#include "BrookPlatform.h"
#include "BrookBondParameters.h"
#include "OpenMMBrookInterface.h"
namespace OpenMM {
/**
* This kernel is invoked to calculate the harmonic angle forces acting on the system.
*/
class BrookCalcHarmonicBondForceKernel : public CalcHarmonicBondForceKernel {
public:
/**
* BrookCalcHarmonicBondForceKernel constructor
*/
BrookCalcHarmonicBondForceKernel( std::string name, const Platform& platform, OpenMMBrookInterface& openMMBrookInterface, System& system );
/**
* BrookCalcHarmonicBondForceKernel destructor
*/
~BrookCalcHarmonicBondForceKernel();
/**
* Initialize the kernel, setting up the values to calculate harmonic bond force & energy
*
* @param system System reference
* @param force HarmonicBondForce reference
*
*/
void initialize( const System& system, const HarmonicBondForce& force );
/**
* Execute the kernel to calculate the forces.
*
* @param positions particle coordiantes
* @param forces output forces
*
*/
void executeForces( ContextImpl& context );
/**
* Execute the kernel to calculate the energy.
*
* @param context the context in which to execute this kernel
*
* @return potential energy associated with the harmonic angle force
*
*/
double executeEnergy( ContextImpl& context );
/**
* Set log file reference
*
* @param log file reference
*
* @return DefaultReturnValue
*
*/
int setLog( FILE* log );
/*
* Get contents of object
*
* @param level of dump
*
* @return string containing contents
*
* */
std::string getContents( int level ) const;
/**
* Get log file reference
*
* @return log file reference
*
*/
FILE* getLog( void ) const;
/**
* Get number of bonds
*
* @return number of bonds
*
*/
int getNumberOfBonds( void ) const;
/**
* Get indices/parameters
*
* @return BrookBondParameters containing particle indices/parameters
*
*/
BrookBondParameters* getBrookBondParameters( void ) const;
private:
static const int NumberOfParticlesInBond = 2;
static const int NumberOfParametersInBond = 2;
// bond name
static const std::string BondName;
// log file reference
FILE* _log;
// Brook bond parameters
BrookBondParameters* _brookBondParameters;
// interface
OpenMMBrookInterface& _openMMBrookInterface;
// System reference
System& _system;
};
} // namespace OpenMM
#endif /* OPENMM_BROOK_CALC_HARMONIC_BOND_FORCE_KERNEL_H_ */
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2009 Stanford University and the Authors. *
* Authors: Mark Friedrichs, Mike Houston *
* Contributors: *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as published *
* by the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* -------------------------------------------------------------------------- */
#include "openmm/OpenMMException.h"
#include "BrookCalcKineticEnergyKernel.h"
#include "BrookStreamImpl.h"
#include <sstream>
using namespace OpenMM;
using namespace std;
/**
* BrookCalcKineticEnergyKernel constructor
*
* @param name name of the stream to create
* @param platform platform
* @param OpenMMBrookInterface OpenMM-Brook interface
* @param System System reference
*
*/
BrookCalcKineticEnergyKernel::BrookCalcKineticEnergyKernel( std::string name, const Platform& platform, OpenMMBrookInterface& openMMBrookInterface, System& system ) :
CalcKineticEnergyKernel( name, platform ), _openMMBrookInterface( openMMBrookInterface ), _system( system ){
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "BrookCalcKineticEnergyKernel::BrookCalcKineticEnergyKernel";
// ---------------------------------------------------------------------------------------
_openMMBrookInterface.setNumberOfParticles( system.getNumParticles() );
_numberOfParticles = system.getNumParticles();
_masses = NULL;
}
/**
* BrookCalcKineticEnergyKernel destructor
*
*/
BrookCalcKineticEnergyKernel::~BrookCalcKineticEnergyKernel( ){
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "BrookCalcKineticEnergyKernel::~BrookCalcKineticEnergyKernel";
// ---------------------------------------------------------------------------------------
delete[] _masses;
}
/**
* Initialize the kernel
*
* @param system System reference
*
*/
void BrookCalcKineticEnergyKernel::initialize( const System& system ){
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "BrookCalcKineticEnergyKernel::initialize";
// ---------------------------------------------------------------------------------------
_numberOfParticles = system.getNumParticles();
// load masses
if( _masses ){
delete[] _masses;
}
_masses = new BrookOpenMMFloat[_numberOfParticles];
for( unsigned int ii = 0; ii < (unsigned int) _numberOfParticles; ii++ ){
_masses[ii] = static_cast<BrookOpenMMFloat>(system.getParticleMass(ii));
}
/*
std::vector<double> masses;
for( unsigned int ii = 0; ii < (unsigned int) _numberOfParticles; ii++ ){
masses.push_back( system.getParticleMass(ii) );
}
_brookVelocityCenterOfMassRemoval = new BrookVelocityCenterOfMassRemoval();
_brookVelocityCenterOfMassRemoval->setup( masses, getPlatform() );
*/
return;
}
/**
* Calculate kinetic energy
*
* @param context ContextImpl reference
*
* @return kinetic energy of the system
*
*/
double BrookCalcKineticEnergyKernel::execute( ContextImpl& context ){
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookCalcKineticEnergyKernel::execute";
// ---------------------------------------------------------------------------------------
//BrookStreamImpl* velocities = _openMMBrookInterface.getParticleVelocities();
//_brookVelocityCenterOfMassRemoval->removeVelocityCenterOfMass( *velocities );
void* dataV = _openMMBrookInterface.getParticleVelocities()->getData( 1 );
float* velocity = (float*) dataV;
if( 0 && _numberOfParticles ){
printf( "BrookCalcKineticEnergyKernel:\n" );
float com[3] = { 0.0, 0.0, 0.0 };
float localEnergy = 0.0f;
int localIndex = 0;
float massSum = 0.0f;
for ( int ii = 0; ii < _numberOfParticles; ii++, localIndex += 3 ){
com[0] += _masses[ii]*velocity[localIndex];
com[1] += _masses[ii]*velocity[localIndex+1];
com[2] += _masses[ii]*velocity[localIndex+2];
localEnergy += _masses[ii]*(velocity[localIndex]*velocity[localIndex] + velocity[localIndex + 1]*velocity[localIndex + 1] + velocity[localIndex + 2]*velocity[localIndex + 2]);
massSum += _masses[ii];
printf( " %d %.3f [%12.5e %12.5e %12.5e]\n", ii, _masses[ii], velocity[localIndex], velocity[localIndex+1], velocity[localIndex+2] );
}
float inverseTotalMass = 1.0f/massSum;
com[0] *= inverseTotalMass;
com[1] *= inverseTotalMass;
com[2] *= inverseTotalMass;
printf( "KE raw=%.5e Com [%12.5e %12.5e %12.5e]\n", 0.5f*localEnergy, com[0], com[1], com[2] );
float newcom[3] = { 0.0, 0.0, 0.0 };
localIndex = 0;
for ( int ii = 0; ii < _numberOfParticles; ii++, localIndex += 3 ){
velocity[localIndex] -= com[0];
velocity[localIndex+1] -= com[1];
velocity[localIndex+2] -= com[2];
newcom[0] += velocity[localIndex];
newcom[1] += velocity[localIndex+1];
newcom[2] += velocity[localIndex+2];
printf( " %d %.3f [%12.5e %12.5e %12.5e]\n", ii, _masses[ii], velocity[localIndex], velocity[localIndex+1], velocity[localIndex+2] );
}
printf( "NewCom [%12.5e %12.5e %12.5e]\n", newcom[0], newcom[1], newcom[2] );
}
int index = 0;
double energy = 0.0;
for( int ii = 0; ii < _numberOfParticles; ii++, index += 3 ){
energy += _masses[ii]*(velocity[index]*velocity[index] + velocity[index + 1]*velocity[index + 1] + velocity[index + 2]*velocity[index + 2]);
}
//printf( " KQ=%12.5e\n", 0.5*energy );
return 0.5*energy;
}
#ifndef OPENMM_BROOK_CALC_KINETIC_ENERGY_KERNEL_H_
#define OPENMM_BROOK_CALC_KINETIC_ENERGY_KERNEL_H_
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2009 Stanford University and the Authors. *
* Authors: Mark Friedrichs, Mike Houston *
* Contributors: *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as published *
* by the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* -------------------------------------------------------------------------- */
#include "openmm/kernels.h"
#include "BrookFloatStreamInternal.h"
#include "OpenMMBrookInterface.h"
#include "BrookVelocityCenterOfMassRemoval.h"
namespace OpenMM {
/**
* Brook class for calculating kinetic energy
*/
class BrookCalcKineticEnergyKernel : public CalcKineticEnergyKernel {
public:
/**
* BrookCalcKineticEnergyKernel constructor
*
* @param name name of the stream to create
* @param platform platform
* @param OpenMMBrookInterface OpenMM-Brook interface
* @param System System reference
*/
BrookCalcKineticEnergyKernel( std::string name, const Platform& platform, OpenMMBrookInterface& openMMBrookInterface, System& system );
/**
* BrookCalcKineticEnergyKernel destructor
*
*/
~BrookCalcKineticEnergyKernel();
/**
* Initialize the kernel
*
* @param system System reference
*
*/
void initialize( const System& system );
/**
* Execute the kernel.
*
* @param context ContextImpl reference
*
*/
double execute( ContextImpl& context );
private:
int _numberOfParticles;
// masses
BrookOpenMMFloat* _masses;
// interface
OpenMMBrookInterface& _openMMBrookInterface;
// System reference
System& _system;
BrookVelocityCenterOfMassRemoval* _brookVelocityCenterOfMassRemoval;
};
} // namespace OpenMM
#endif /* OPENMM_BROOK_CALC_KINETIC_ENERGY_KERNEL_H_ */
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2009 Stanford University and the Authors. *
* Authors: Mark Friedrichs, Mike Houston *
* Contributors: *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as published *
* by the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* -------------------------------------------------------------------------- */
#include "openmm/OpenMMException.h"
#include "BrookStreamImpl.h"
#include "BrookCalcNonbondedForceKernel.h"
#include "openmm/NonbondedForce.h"
#include <cmath>
#include <limits>
#include <sstream>
using namespace OpenMM;
using namespace std;
const std::string BrookCalcNonbondedForceKernel::BondName = "LJ14";
/**
* BrookCalcNonbondedForceKernel constructor
*
* @param name kernel name
* @param platform platform
* @param openMMBrookInterface OpenMMBrookInterface reference
* @param system System reference
*
*/
BrookCalcNonbondedForceKernel::BrookCalcNonbondedForceKernel( std::string name, const Platform& platform,
OpenMMBrookInterface& openMMBrookInterface, System& system ) :
CalcNonbondedForceKernel( name, platform ), _openMMBrookInterface( openMMBrookInterface ), _system( system ){
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "BrookCalcNonbondedForceKernel::BrookCalcNonbondedForceKernel";
// ---------------------------------------------------------------------------------------
_numberOfParticles = system.getNumParticles();
_openMMBrookInterface.setNumberOfParticles( system.getNumParticles() );
_brookBondParameters = NULL;
_log = NULL;
const BrookPlatform& brookPlatform = dynamic_cast<const BrookPlatform&> (platform);
if( brookPlatform.getLog() != NULL ){
setLog( brookPlatform.getLog() );
}
}
/**
* BrookCalcNonbondedForceKernel destructor
*
*/
BrookCalcNonbondedForceKernel::~BrookCalcNonbondedForceKernel( ){
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "BrookCalcNonbondedForceKernel::BrookCalcNonbondedForceKernel";
// ---------------------------------------------------------------------------------------
delete _brookBondParameters;
}
/**
* Get log file reference
*
* @return log file reference
*
*/
FILE* BrookCalcNonbondedForceKernel::getLog( void ) const {
return _log;
}
/**
* Set log file reference
*
* @param log file reference
*
* @return DefaultReturnValue
*
*/
int BrookCalcNonbondedForceKernel::setLog( FILE* log ){
_log = log;
return BrookCommon::DefaultReturnValue;
}
/**
* Initialize object
*
* @param system System reference (currently not used)
* @param force NonbondedForce reference -- extract charge, and vdw parameters from this object
* @param exclusions list of execlusions
*
* @return DefaultReturnValue
*
*/
void BrookCalcNonbondedForceKernel::initialize( const System& system, const NonbondedForce& force ){
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookCalcNonbondedForceKernel::initialize";
static const int PrintOn = 0;
// ---------------------------------------------------------------------------------------
FILE* log = getLog();
if( PrintOn && log ){
(void) fprintf( log, "%s begin\n", methodName.c_str() ); fflush( log );
} else {
log = NULL;
}
_numberOfParticles = force.getNumParticles();
/*
nonbondedMethod = CalcNonbondedForceKernel::NonbondedMethod(force.getNonbondedMethod());
nonbondedCutoff = (RealOpenMM) force.getCutoffDistance();
Vec3 boxVectors[3];
force.getPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]);
periodicBoxSize[0] = (RealOpenMM) boxVectors[0][0];
periodicBoxSize[1] = (RealOpenMM) boxVectors[1][1];
periodicBoxSize[2] = (RealOpenMM) boxVectors[2][2];
if (nonbondedMethod == NoCutoff)
neighborList = NULL;
else
neighborList = new NeighborList();
*/
// ---------------------------------------------------------------------------------------
// nonbonded
BrookNonBonded& brookNonBonded = _openMMBrookInterface.getBrookNonBonded();
// charge & LJ parameters
std::vector<std::vector<double> > nonbondedParameters;
nonbondedParameters.resize( _numberOfParticles );
for( int ii = 0; ii < _numberOfParticles; ii++ ){
double charge, radius, depth;
force.getParticleParameters( ii, charge, radius, depth );
nonbondedParameters[ii].push_back( charge );
nonbondedParameters[ii].push_back( radius );
nonbondedParameters[ii].push_back( depth );
}
// Go through the exclusions.
std::vector<std::set<int> > exclusions(_numberOfParticles);
std::vector<int> nb14s;
for (int i = 0; i < force.getNumExceptions(); i++) {
int particle1, particle2;
double chargeProd, sigma, epsilon;
force.getExceptionParameters(i, particle1, particle2, chargeProd, sigma, epsilon);
exclusions[particle1].insert(particle2);
exclusions[particle2].insert(particle1);
if (chargeProd != 0.0 || epsilon != 0.0)
nb14s.push_back(i);
}
brookNonBonded.setup( _numberOfParticles, nonbondedParameters, exclusions, getPlatform() );
_openMMBrookInterface.setTriggerForceKernel( this );
_openMMBrookInterface.setTriggerEnergyKernel( this );
// echo contents
if( log ){
std::string contents = brookNonBonded.getContentsString( );
(void) fprintf( log, "%s brookNonBonded::contents\n%s", methodName.c_str(), contents.c_str() );
(void) fflush( log );
}
// nonbonded 14 ixns
initialize14Interactions( system, force, nb14s );
}
/**
* Initialize the kernel, setting up the values of all the force field parameters.
*
* @param system System reference
* @param force HarmonicLJ14Force reference
* @param nb14s which of the exceptions need to be calculated
*/
void BrookCalcNonbondedForceKernel::initialize14Interactions( const System& system, const NonbondedForce& force, const std::vector<int>& nb14s ){
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookCalcNonbondedForceKernel::initialize14Interactions";
// ---------------------------------------------------------------------------------------
FILE* log = getLog();
//(void) fprintf( log, "%s begin\n", methodName.c_str() ); fflush( log );
// ---------------------------------------------------------------------------------------
// create _brookBondParameters object containing particle indices/parameters
int numberOf14Forces = nb14s.size();
if( numberOf14Forces > 0 ){
_brookBondParameters = new BrookBondParameters( BondName, NumberOfParticlesInBond, NumberOfParametersInBond, numberOf14Forces, getLog() );
for( int ii = 0; ii < numberOf14Forces; ii++ ){
int particle1, particle2;
double charge, radius, depth;
int particles[NumberOfParticlesInBond];
double parameters[NumberOfParametersInBond];
force.getExceptionParameters( nb14s[ii], particle1, particle2, charge, radius, depth );
//(void) fprintf( log, "%s idx=%d [%d %d] [%f %f %f]\n", methodName.c_str(), ii, particle1, particle2, charge, radius, depth );
particles[0] = particle1;
particles[1] = particle2;
parameters[0] = charge;
parameters[1] = radius;
parameters[2] = depth;
_brookBondParameters->setBond( ii, particles, parameters );
}
_openMMBrookInterface.setNonBonded14ForceParameters( _brookBondParameters );
if( log ){
std::string contents = _brookBondParameters->getContentsString( );
(void) fprintf( log, "%s contents:\n%s", methodName.c_str(), contents.c_str() );
(void) fflush( log );
}
} else if( log ){
(void) fprintf( log, "%s no 14 ixns\n", methodName.c_str() );
(void) fflush( log );
}
// ---------------------------------------------------------------------------------------
}
/**
* Execute the kernel to calculate the nonbonded forces
*
* @param context ContextImpl context
*
*/
void BrookCalcNonbondedForceKernel::executeForces( ContextImpl& context ){
// ---------------------------------------------------------------------------------------
static const std::string methodName = "BrookCalcNonbondedForceKernel::executeForces";
// ---------------------------------------------------------------------------------------
if( _openMMBrookInterface.getTriggerForceKernel() == this ){
_openMMBrookInterface.computeForces( context );
}
// ---------------------------------------------------------------------------------------
}
/**
* Execute the kernel to calculate the energy.
*
* @param context ContextImpl context
*
* @return potential energy due to the NonbondedForce
* Currently always return 0.0 since energies not calculated on gpu
*
*/
double BrookCalcNonbondedForceKernel::executeEnergy( ContextImpl& context ){
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "BrookCalcNonbondedForceKernel::executeEnergy";
// ---------------------------------------------------------------------------------------
if( _openMMBrookInterface.getTriggerEnergyKernel() == this ){
return (double) _openMMBrookInterface.computeEnergy( context, _system );
} else {
return 0.0;
}
}
#ifndef OPENMM_BROOK_CALC_NONBONDED_FORCE_KERNEL_H_
#define OPENMM_BROOK_CALC_NONBONDED_FORCE_KERNEL_H_
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2009 Stanford University and the Authors. *
* Authors: Mark Friedrichs, Mike Houston *
* Contributors: *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as published *
* by the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* -------------------------------------------------------------------------- */
#include "openmm/kernels.h"
#include "OpenMMBrookInterface.h"
#include "openmm/NonbondedForce.h"
namespace OpenMM {
/**
* This kernel is invoked by NonbondedForce to calculate the forces acting on the system.
*/
class BrookCalcNonbondedForceKernel : public CalcNonbondedForceKernel {
public:
BrookCalcNonbondedForceKernel( std::string name, const Platform& platform, OpenMMBrookInterface& openMMBrookInterface, System& system );
~BrookCalcNonbondedForceKernel();
/**
* Initialize the kernel
*
* @param system the System this kernel will be applied to
* @param force the NonbondedForce this kernel will be used for
*/
void initialize( const System& system, const NonbondedForce& force );
/**
* Initialize the 14 ixns
*
* @param system the System this kernel will be applied to
* @param force the NonbondedForce this kernel will be used for
* @param nb14s which of the exceptions need to be calculated
*/
void initialize14Interactions( const System& system, const NonbondedForce& force, const std::vector<int>& nb14s );
/**
* Execute the kernel to calculate the forces.
*
* @param positions a Stream of type Double3 containing the position (x, y, z) of each particle
* @param forces a Stream of type Double3 containing the force (x, y, z) on each particle. On entry, this contains the forces that
* have been calculated so far. The kernel should add its own forces to the values already in the stream.
*/
void executeForces( const Stream& positions, Stream& forces );
/**
* Execute the kernel to calculate the forces.
*
* @param context the context in which to execute this kernel
*/
void executeForces( ContextImpl& context );
/**
* Execute the kernel to calculate the energy.
*
* @param positions a Stream of type Double3 containing the position (x, y, z) of each particle
*
* @return the potential energy due to the NonbondedForce
*
* Currently always return 0.0 since energies not calculated on gpu
*/
double executeEnergy( const Stream& positions );
/**
* Execute the kernel to calculate the energy.
*
* @param context the context in which to execute this kernel
* @return the potential energy due to the NonbondedForce
*/
double executeEnergy( ContextImpl& context );
/**
* Set log file reference
*
* @param log file reference
*
* @return DefaultReturnValue
*
*/
int setLog( FILE* log );
/*
* Get contents of object
*
* @param level of dump
*
* @return string containing contents
*
* */
std::string getContents( int level ) const;
/**
* Get log file reference
*
* @return log file reference
*
*/
FILE* getLog( void ) const;
private:
// LJ14 'bond' name
static const std::string BondName;
// number of LJ14 particles/parameters in 'bond'
static const int NumberOfParticlesInBond = 2;
static const int NumberOfParametersInBond = 3;
// log file reference
FILE* _log;
// number of particles
int _numberOfParticles;
OpenMMBrookInterface& _openMMBrookInterface;
System& _system;
BrookBondParameters* _brookBondParameters;
};
} // namespace OpenMM
#endif /* OPENMM_BROOK_CALC_NONBONDED_FORCE_KERNEL_H_ */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment